详谈关系数据库中的“键”(续1)
详谈关系数据库中的“键”(续1)
(1)天然主键
在现实生活中存在着许多看起来可以惟一地标识一行记录的值,如:身份证号码、汽车牌照号码等。数据库逻辑模式设计往往会使用这些天然的主键,尽管这些天然主键中没有哪一个是十分可靠的。
可以让用户把它们当作查找和命名一行记录的“主键”,但绝不能把它们作为实际的主键。
如果必须使用一个天然主键,则必须保证对于每一个引用了这个天然主键的外键都启用了级联更新选项,这样在更新主键时就不会破坏参照完整性了。
(2)SQL Server的主键约束
SQL Server使用约束来维护主键和外键。约束的用途在于:确保新数据满足指定的要求,否则将拒绝相应的数据修改操作。
主键约束实际上是通过Unique约束(不是空置约束)以及聚集或者非聚集惟一索引来实现的。
注:主键应当是没有实际意义的、单列的、计算机生成的、不可编辑的,而且对于用户来说应当是不可见的。另外,防止用户查看和操作键是一个成功的数库开发人员所要达到的主要目标之一。
企业管理器使用聚集索引创建主键,这种实现方法并不好。如果要使用企业管理器这个图形工具来创建物理模式,应当手工将主键索引重新设置为非聚集索引。在代码中,可以使用以下两种方式之一把某个(某些)列设置为主键:
CREATE TABLE dbo.Guide (
GuideID INT IDENTITY NOT NULL PRIMARY KEY NONCLUSTERED ,
... ...
或者
ALTER TABLE dbo.Guide ADD CONSTRAINT
PK_Guide PRIMARY KEY NONCLUSTERED (GuideID)
... ...
有两种类型最适合于做主键:标识列(IDNETITY)和全局惟一标识符列(GUID)。
A. 使用IDENTITY。
到目前为止,大多数广为使用的主键创建方法都与标识列的使用有关。当新的记录行插入到数据库中时,标识列都会为它们生成连续的整数。你还可以任意的设定标识列的种子值和增量值。
标识列具有以下的优点:a. 整数比GUID更容易人工识别和编辑。
b. 整数比GUID占用空间小而且快。当然,这样的性能差别只有当你循环执行数千个select语句才能显现出来。
标识列的值是在插入新的记录行时由SQL Server创建的。除非将set insert_identity选项设置为true,否则,试图在标识列中插入数据或者更新标识列中的数据都会产生错误。
B. 使用GUID。
SQL Server的uniqueidentifier数据类型与COM的全局惟一标识符相对应。虽然标识列和GUID都是惟一的,但与标识列相比,GUID可以在更大范围内保证唯一性。它具有如下优点:
a. 复制使用GUID主键的数据库时,不必额外作全面的检查。
b. GUID值的随机性可以减少数据库的热点。
c. GUID可以避免用户使用具有实际意义的主键,或者为主键赋予实际的意义。
d. GUID可以避免这样的连接错误,即:查询时连接了错误的表,但系统依旧返回了结果。因为如果使用了GUID,这些表的记录行在键所对应的那些列上是不可能取同样的整数值的。
e. GUID的值是用不完的。
f. 可以使用多种方法来生成GUID的值,包括:使用列的默认值、select语句的表达式或者select语句之前的代码,因此,使用GUID编程要容易的多。此外,使用GUID可以避免使用标识列时会出现的数据修改问题。
在下面的脚本中,将PorductID列的数据类型设置为uniqueidentitfier,并指定它不能够取空值。该列的rowguidcol属性被设置为true,这使得复制程序能够检测并使用它。它的默认值是新生成的uniqueidentifier。Product表将它作为主键,它使用了非聚集的惟一索引。
CREATE TABLE dbo.Product (
ProductID UNIQUEIDENTIFIER NOT NULL
ROWGUIDCOL DEFAULT (NEWID())
PRIMARY KEY NONCLUSTERED,
... ...