首先让我们谈下主键约束本身。顾名思义它只是个约束,使用这个约束你告诉SQL Server你想在特定列或特定一组列有唯一值。下列代码显示了一个非常简单的表定义,在第1个Col列指定了主键约束。
1 CREATE TABLE Foo 2 ( 3 Col1 INT NOT NULL PRIMARY KEY, 4 Col2 INT NOT NULL, 5 Col3 INT NOT NULL 6 ) 7 GO
现在当你往表里插入记录,SQL Server确保在Col列总有唯一值。如果你尝试插入重复值,SQL Server返回错误信息。
1 -- Try to insert a duplicate value 2 INSERT INTO Foo Values (1, 1, 1), (1, 2, 2) 3 GO
1 -- SQL Server generates by default a Unique Clustered Index 2 SELECT * FROM sys.indexes 3 WHERE object_id = OBJECT_ID('Foo') 4 GO
我已经说过,默认是创建唯一聚集索引。你也可以使用如下代码所示的唯一非聚集索引来强制执行主键约束。
1 -- Enforces the Primary Key constraint with a Unique Non-Clustered Index 2 CREATE TABLE Foo1 3 ( 4 Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED, 5 Col2 INT NOT NULL, 6 Col3 INT NOT NULL 7 ) 8 GO
当你指定主键约束时,你可以指定下列2个选项:
1 -- SQL Server has generated now a Unique Non-Clustered Index to 2 -- enforce the Primary Key constraint 3 SELECT * FROM sys.indexes 4 WHERE object_id = OBJECT_ID('Foo1') 5 GO
因此在SQL Server里并不意味着主键和聚集索引总是一样的。默认是一样的,但你可要修改这个如果你想要的话。主键约束总是在逻辑层,索引结构在是物理层来强制约束本身。
1 -- Create the Primary Key constraint on an ever-increasing 2 -- key column 3 CREATE TABLE Foo2 4 ( 5 Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED, 6 Col2 UNIQUEIDENTIFIER NOT NULL, 7 Col3 INT NOT NULL 8 ) 9 GO 10 11 -- Create the Clustered Index on a random key column 12 CREATE UNIQUE CLUSTERED INDEX ci_Col2 ON Foo2(Col2) 13 GO
1 -- Now we have a Clustered and Non-Clustered Index 2 SELECT * FROM sys.indexes 3 WHERE object_id = OBJECT_ID('Foo2') 4 GO
在SQL Server里,主键约束和聚集索引并不一样的。默认SQL Server使用唯一聚集索引来强制主键约束。但如果你想要的话,你可以使用唯一非聚集索引来代替。但这个方法默认是没有太大意义,因为你需要处理相关问题(最后页插入闩锁竞争)来使用这个方法。
感谢关注!