标识列和GUID列

在SQL Server的表中,可能会有两种特殊的列。一种是标识列(Identity),一种是全球唯一标识符(GUID)

首先看第一种

通过使用 IDENTITY 属性可以实现标识符列。这使得开发人员可以为表中所插入的第一行指定一个标识号(Identity Seed 属性),并确定要添加到种子上的增量(Identity Increment 属性)以确定后面的标识号。将值插入到有标识符列的表中之后,数据库引擎会通过向种子添加增量来自动生成下一个标识值。当您向现有表中添加标识符列时,还会将标识号添加到现有表行中,并按照最初插入这些行的顺序应用种子值和增量值。同时还为所有新添加的行生成标识号。不能修改现有表列来添加 IDENTITY 属性。

在用 IDENTITY 属性定义标识符列时,注意下列几点:

  • 一个表只能有一个使用 IDENTITY 属性定义的列,且必须通过使用 decimalintnumericsmallintbiginttinyint 数据类型来定义该列。
  • 可指定种子和增量。二者的默认值均为 1。
  • 标识符列不能允许为 Null 值,也不能包含 DEFAULT 定义或对象。
  • 在设置 IDENTITY 属性后,可以使用 $IDENTITY 关键字在选择列表中引用该列。还可以通过名称引用该列。
  • OBJECTPROPERTY 函数可用于确定一个表是否具有 IDENTITY 列,COLUMNPROPERTY 函数可用于确定 IDENTITY 列的名称。
  • 通过使值能够显式插入,SET IDENTITY_INSERT 可用于禁用列的 IDENTITY 属性。

    注意:

    如果在经常进行删除操作的表中存在标识符列,那么标识值之间可能会出现断缺。已删除的标识值不再重新使用。要避免出现这类断缺,请勿使用 IDENTITY 属性。而是可以在插入行时,以标识符列中现有的值为基础创建一个用于确定新标识符值的触发器。

 

与标识列有关几个特殊关键字

SELECT $IDENTITY FROM Adventureworks.Sales.SalesOrderHeader
SELECT IDENTITYCOL FROM Adventureworks.Sales.SalesOrderHeader

 

还有一个系统变量,可以返回当前最新的标识值: @@identity

 

然后来看看全球唯一标识符列

尽管 IDENTITY 属性在一个表内自动进行行编号,但具有各自标识符列的各个表可以生成相同的值。这是因为 IDENTITY 属性仅在使用它的表上保证是唯一的。如果应用程序生成一个标识符列,并且该列在整个数据库或全球联网的所有计算机上的所有数据库中必须是唯一的,请使用 uniqueidentifier 数据类型和 NEWID 或 NEWSEQUENTIALID() 函数。此外,还可以应用 ROWGUIDCOL 属性以指示新列是行 GUID 列。与使用 IDENTITY 属性定义的列不同,数据库引擎不会为 uniqueidentifier 类型的列自动生成值。若要插入全局唯一值,请为该列创建 DEFAULT 定义来使用 NEWID 或 NEWSEQUENTIALID 函数生成全局唯一值。有关详细信息,请参阅使用 uniqueidentifier 数据。

可以使用 $ROWGUID 关键字在选择列表中引用具有 ROWGUICOL 属性的列。这与通过使用 $IDENTITY 关键字可以引用 IDENTITY 列的方法类似。一个表只能有一个 ROWGUIDCOL 列,且必须通过使用 uniqueidentifier 数据类型定义该列。OBJECTPROPERTY (Transact-SQL) 函数可用于确定一个表是否具有 ROWGUIDCOL 列,COLUMNPROPERTY (Transact-SQL) 函数可用于确定 ROWGUIDCOL 列的名称。

以下示例创建 uniqueidentifier 列作为主键的表。此示例在 DEFAULT 约束中使用 NEWSEQUENTIALID() 函数为新行提供值。将 ROWGUIDCOL 属性应用到 uniqueidentifier 列,以便可以使用 $ROWGUID 关键字对其进行引用。

CREATE TABLE dbo.Globally_Unique_Data
(guid uniqueidentifier CONSTRAINT Guid_Default DEFAULT NEWSEQUENTIALID() ROWGUIDCOL,
    Employee_Name varchar(60)
CONSTRAINT Guid_PK PRIMARY KEY (guid) );