Ayrıca birincil anahtar olan kümelenmiş bir dizin oluşturmak için SQL Server sözdizimi şöyledir:
CREATE TABLE dbo.c
(
c1 INT NOT NULL,
c2 INT NOT NULL,
CONSTRAINT PK_c
PRIMARY KEY CLUSTERED (c1, c2)
);
Yorumunuza göre: "PK'nin adlandırılmış bir dizin kullanması", yukarıdaki kod birincil anahtar dizininin "PK_c" olarak adlandırılmasına neden olur.
Birincil anahtar ile kümeleme anahtarının aynı sütunlar olması gerekmez. Bunları ayrı ayrı tanımlayabilirsiniz. Yukarıdaki örnekte, CLUSTERED
anahtar kelimeyi olarak değiştirin NONCLUSTERED
ve CREATE INDEX
sözdizimini kullanarak kümelenmiş bir dizin ekleyin :
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);
SQL Server kümelenmiş dizin olan tablo, onlar bir-ve-aynıdır. Kümelenmiş bir dizin, tabloda depolanan satırların mantıksal sırasını tanımlar. İlk örneğimde, satırlar c1
ve c2
sütunlarının sırasıyla sıralanır . Kümelenme anahtarı da birincil anahtar, bir kombinasyon olarak tanımlanır yana c1
ve c2
tablo çapında farklı olmalıdır.
İkinci örnekte, birincil anahtar c1
ve c2
sütunlarından oluşur , ancak kümeleme anahtarı yalnızca c2
sütundur. İfadede UNIQUE
özniteliği belirtmediğim için CREATE INDEX
, küme anahtarının ( c2
) tablo boyunca benzersiz olması gerekmez. SQL Server tarafından otomatik olarak bir "benzersizleştirici" c2
oluşturulur ve kümeleme anahtarını oluşturmak için sütundaki değerlere eklenir . Bu kümeleme anahtarı, artık benzersiz olduğundan, tabloda oluşturulan diğer dizinlerde satır kimliği olarak kullanılacaktır.
Kümeleme anahtarının depodaki satırların düzenini denetlediğini kanıtlamak için, belgesiz işlevi kullanabilirsiniz fn_PhysLocCracker(%%PHYSLOC%%)
. Aşağıdaki kod, satırları c2
küme anahtarı olarak tanımladığım sütun sırasına göre diskte düzenlenmiş olarak gösterir :
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;
Benim tempdb sonuçları :
Yukarıdaki görüntüde, ilk üç sütun fn_PhysLocCracker
, diskteki satırların fiziksel sırasını gösteren işlevden çıkarılır . Kümeleme anahtarı olan değerle slot_id
kilit adımının arttığını görebilirsiniz c2
. Birincil anahtar dizini, SQL Server'ı birincil anahtarı taramaktan sonuç döndürmeye zorlayarak satırları farklı bir sırada depolar:
SELECT pkt.c1
, pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN);
ORDER BY
Birincil anahtar dizinindeki öğelerin sırasını göstermeye çalıştığım için, yukarıdaki ifadede bir cümle kullanmadım .
Yukarıdaki sorgudan çıktı:
İşleve bakarak fn_PhysLocCracker
, birincil anahtar dizininin fiziksel sırasını görebiliriz.
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;
Yalnızca dizinin kendisinden okuduğumuzdan, yani sorguda dizinin dışındaki sütunlara başvurulmadığından, %%PHYSLOC%%
değerler dizinin kendisindeki sayfaları temsil eder.
Sonuçlar:
create table c (c1 int not null primary key, c2 int)