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 CLUSTERED
kata kunci menjadi NONCLUSTERED
, lalu tambahkan indeks berkerumun menggunakan CREATE INDEX
sintaksis:
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 c1
dan c2
kolom. Karena kunci pengelompokan juga didefinisikan sebagai kunci utama, kombinasi dari c1
dan c2
harus unik untuk seluruh tabel.
Dalam contoh kedua, kunci utama terdiri dari kolom c1
dan c2
, namun kunci pengelompokan hanya c2
kolom. Karena saya tidak menentukan UNIQUE
atribut dalam CREATE INDEX
pernyataan, kunci pengelompokan ( c2
) tidak harus unik di seluruh tabel. "Uniquifier" akan secara otomatis dibuat oleh SQL Server dan ditambahkan ke nilai-nilai di c2
kolom 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 c2
kolom, 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_PhysLocCracker
fungsi, yang menunjukkan urutan fisik baris pada disk. Anda dapat melihat slot_id
nilai meningkatkan kunci-langkah dengan c2
nilai, 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 BY
klausa dalam pernyataan di atas karena saya mencoba untuk menunjukkan urutan item dalam indeks kunci utama.
Output dari query di atas adalah:
Melihat ke fn_PhysLocCracker
fungsi, 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)