Sintaks SQL Server untuk membuat indeks berkerumun yang juga merupakan kunci utama adalah:
CREATE TABLE dbo.c
(
c1 INT NOT NULL,
c2 INT NOT NULL,
CONSTRAINT PK_c
PRIMARY KEY CLUSTERED (c1, c2)
);
Sejauh komentar Anda: "membuat PK menggunakan indeks bernama", kode di atas akan menghasilkan indeks kunci utama yang dinamai "PK_c".
Kunci primer dan kunci pengelompokan tidak harus kolom yang sama. Anda dapat mendefinisikannya secara terpisah. Pada contoh di atas, ubah CLUSTEREDkata kunci menjadi NONCLUSTERED, lalu tambahkan indeks berkerumun menggunakan CREATE INDEXsintaksis:
CREATE TABLE dbo.c
(
c1 INT,
c2 INT,
CONSTRAINT PK_c
PRIMARY KEY NONCLUSTERED (c1, c2)
);
CREATE CLUSTERED INDEX CX_c ON dbo.c (c2);
Dalam SQL Server indeks berkerumun adalah tabel, mereka satu-dan-sama. Indeks berkerumun mendefinisikan urutan logis dari baris yang disimpan dalam tabel. Dalam contoh pertama saya, baris disimpan dalam urutan nilai-nilai c1dan c2kolom. Karena kunci pengelompokan juga didefinisikan sebagai kunci utama, kombinasi dari c1dan c2harus unik untuk seluruh tabel.
Dalam contoh kedua, kunci utama terdiri dari kolom c1dan c2, namun kunci pengelompokan hanya c2kolom. Karena saya tidak menentukan UNIQUEatribut dalam CREATE INDEXpernyataan, kunci pengelompokan ( c2) tidak harus unik di seluruh tabel. "Uniquifier" akan secara otomatis dibuat oleh SQL Server dan ditambahkan ke nilai-nilai di c2kolom untuk membuat kunci pengelompokan. Kunci pengelompokan ini, karena sekarang unik, kemudian akan digunakan sebagai id baris dalam indeks lain yang dibuat di tabel.
Untuk membuktikan kunci pengelompokan mengontrol tata letak baris dalam penyimpanan, Anda dapat menggunakan fungsi tidak berdokumen fn_PhysLocCracker(%%PHYSLOC%%),. Kode berikut menunjukkan baris diletakkan pada disk sesuai urutan c2kolom, yang telah saya definisikan sebagai kunci pengelompokan:
USE tempdb;
CREATE TABLE dbo.PKTest
(
c1 INT NOT NULL
, c2 INT NOT NULL
, c3 VARCHAR(256) NOT NULL
);
ALTER TABLE PKTest
ADD CONSTRAINT PK_PKTest
PRIMARY KEY NONCLUSTERED (c1, c2);
CREATE CLUSTERED INDEX CX_PKTest
ON dbo.PKTest(c2);
TRUNCATE TABLE dbo.PKTest;
INSERT INTO dbo.PKTest (c1, c2, c3)
SELECT TOP(25) o1.object_id / o2.object_id, o2.object_id, o1.name + '.' + o2.name
FROM sys.objects o1
, sys.objects o2
WHERE o1.object_id >0
and o2.object_id > 0;
SELECT plc.file_id
, plc.page_id
, plc.slot_id
, pk.*
FROM dbo.PKTest pk
CROSS APPLY fn_PhysLocCracker(%%PHYSLOC%%) plc;
Hasil dari tempdb saya , adalah:

Pada gambar di atas, tiga kolom pertama adalah output dari fn_PhysLocCrackerfungsi, yang menunjukkan urutan fisik baris pada disk. Anda dapat melihat slot_idnilai meningkatkan kunci-langkah dengan c2nilai, yang merupakan kunci pengelompokan. Indeks kunci utama menyimpan baris dalam urutan yang berbeda, yang dapat dilihat dengan memaksa SQL Server untuk mengembalikan hasil dari pemindaian kunci utama:
SELECT pkt.c1
, pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN);
Catatan, saya tidak menggunakan ORDER BYklausa dalam pernyataan di atas karena saya mencoba untuk menunjukkan urutan item dalam indeks kunci utama.
Output dari query di atas adalah:

Melihat ke fn_PhysLocCrackerfungsi, kita dapat melihat urutan fisik dari indeks kunci primer.
SELECT plc.file_id
, plc.page_id
, plc.slot_id
, pkt.c1
, pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN)
CROSS APPLY fn_PhysLocCracker(%%PHYSLOC%%) plc;
Karena kita secara eksklusif membaca dari indeks itu sendiri, yaitu tidak ada kolom di luar indeks yang direferensikan dalam kueri, %%PHYSLOC%%nilai - nilai mewakili halaman dalam indeks itu sendiri.
Hasil:

create table c (c1 int not null primary key, c2 int)