表通常具有包含唯一标识表中每一行的值的一列或一组列。 这样的一列或多列称为表的主键 (PK),用于强制表的实体完整性。 由于主键约束可保证数据的唯一性,因此经常对标识列定义这种约束。
如果为表指定了主键约束,数据库引擎将通过为主键列自动创建唯一索引来强制数据的唯一性。 当在查询中使用主键时,此索引还允许对数据进行快速访问。 如果对多列定义了主键约束,则一列中的值可能会重复,但来自主键约束定义中所有列的值的任何组合必须唯一。
如下图所示,Purchasing.ProductVendor 表中的 ProductID 和 VendorID 列构成了针对此表的复合主键约束。 这确保了 ProductVendor 表中的每个行都具有ProductID 和 VendorID 的一个唯一组合。 这样可以防止插入重复的行。
-
一个表只能包含一个主键约束。
-
主键不能超过 16 列且总密钥长度不能超过 900 个字节。
-
由主键约束生成的索引不会使表中的索引数超过 999 个非聚集索引和 1 个聚集索引。
-
如果没有为主键约束指定聚集或非聚集索引,并且表中没有聚集索引,则使用聚集索引。
-
在主键约束中定义的所有列都必须定义为不为 Null。 如果没有指定为 Null 性,则参与主键约束的所有列的为 Null 性都将设置为不为 Null。
-
如果在 CLR 用户定义类型的列中定义主键,则该类型的实现必须支持二进制排序。
引用完整性
尽管外键约束的主要目的是控制可以存储在外键表中的数据,但它还可以控制对主键表中数据的更改。 例如,如果在 Sales.SalesPerson 表中删除一个销售人员行,而这个销售人员的 ID 由 Sales.SalesOrderHeader 表中的销售订单使用,则这两个表之间关联的完整性将被破坏;SalesOrderHeader 表中删除的销售人员的销售订单因为与SalesPerson 表中的数据没有链接而变得孤立了。
外键约束防止这种情况发生。 如果主键表中数据的更改使之与外键表中数据的链接失效,则这种更改将无法实现,从而确保了引用完整性。 如果试图删除主键表中的行或更改主键值,而该主键值与另一个表的外键约束中的值相对应,则该操作将失败。 若要成功更改或删除外键约束中的行,必须先在外键表中删除或更改外键数据,这会将外键链接到不同的主键数据。