La syntaxe SQL Server pour créer un index cluster qui est également une clé primaire est la suivante:
CREATE TABLE dbo.c
(
c1 INT NOT NULL,
c2 INT NOT NULL,
CONSTRAINT PK_c
PRIMARY KEY CLUSTERED (c1, c2)
);
En ce qui concerne votre commentaire: "faire en sorte qu'un PK utilise un index nommé", le code ci-dessus entraînera l'index de la clé primaire qui sera nommé "PK_c".
La clé primaire et la clé de cluster ne doivent pas nécessairement être les mêmes colonnes. Vous pouvez les définir séparément. Dans l'exemple ci-dessus, remplacez le CLUSTERED
mot - clé par NONCLUSTERED
, puis ajoutez simplement un index cluster à l'aide de la CREATE INDEX
syntaxe:
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);
Dans SQL Server, l'index cluster est la table, ils sont identiques. Un index cluster définit l'ordre logique des lignes stockées dans la table. Dans mon premier exemple, les lignes sont stockées dans l'ordre des valeurs des colonnes c1
et c2
. Étant donné que la clé de clustering est également définie comme clé primaire, la combinaison de c1
et c2
doit être unique à l'échelle de la table.
Dans le deuxième exemple, la clé primaire est composée des colonnes c1
et c2
, mais la clé de clustering est juste la c2
colonne. Étant donné que je n'ai pas spécifié l' UNIQUE
attribut dans l' CREATE INDEX
instruction, la clé de clustering ( c2
) n'est pas requise pour être unique sur la table. Un "uniquifier" sera automatiquement créé par SQL Server et ajouté aux valeurs de la c2
colonne pour créer la clé de clustering. Cette clé de cluster, car elle est désormais unique, sera ensuite utilisée comme identifiant de ligne dans d'autres index créés sur la table.
Afin de prouver les contrôles clés de clustering la mise en page des lignes de stockage, vous pouvez utiliser la fonction non documentée, fn_PhysLocCracker(%%PHYSLOC%%)
. Le code suivant montre que les lignes sont disposées sur le disque dans l'ordre de la c2
colonne, que j'ai définie comme clé de clustering:
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;
Les résultats de mon tempdb sont:
Dans l'image ci-dessus, les trois premières colonnes sont sorties de la fn_PhysLocCracker
fonction, montrant l'ordre physique des lignes sur le disque. Vous pouvez voir que la slot_id
valeur augmente l'étape de verrouillage avec la c2
valeur, qui est la clé de clustering. L'index de clé primaire stocke les lignes dans un ordre différent, ce qui peut être vu en forçant SQL Server à renvoyer les résultats de l'analyse de la clé primaire:
SELECT pkt.c1
, pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN);
Remarque, je n'ai pas utilisé de ORDER BY
clause dans l'instruction ci-dessus car j'essaie d'afficher l'ordre des éléments dans l'index de clé primaire.
Le résultat de la requête ci-dessus est:
En regardant la fn_PhysLocCracker
fonction, nous pouvons voir l'ordre physique de l'index de clé primaire.
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;
Puisque nous lisons exclusivement à partir de l'index lui-même, c'est-à-dire qu'aucune colonne en dehors de l'index n'est référencée dans la requête, les %%PHYSLOC%%
valeurs représentent les pages de l'index lui-même.
Les resultats:
create table c (c1 int not null primary key, c2 int)