列屬性:RowGUIDCol、Identity 和 not for replication


在SQL Server中,創建數據表,需要為表設置合適的屬性和約束,例如,自增列,非空,主鍵等,以滿足業務的需求,一般來說,數據表存儲的實體都應該唯一標識,使用ID列或GUID列來充當候選主鍵是可以的,相應地,數據表的列(Column)有兩個特殊的屬性:

  • RowGUIDCol:用於標識UniqueIdentifier 類型的數據列,該列可以通過內置函數 $ROWGUID 來引用;
  • Identity:用於標識整數類型(int,bigint,tinyint,smallint,decimal(p,0))的列是自增列,該列可以通過內置函數$IDENTITY 來引用;

在每個表中,只能有一列被標識為RowGUIDCol,只能有一列被標識為Identity;

一,屬性說明

1,自增屬性

自增屬性的定義是IDENTITY(seed,increment),屬性Identity標識的列是自增列,每個表只能有一個自增列。Identity屬性必須設置兩個參數seed和increment,默認值是:seed=1,increment=1,即Identity(1,1),seed參數是自增列的第一個值,increment參數是每次數據增加的大小。例如,IDENTITY(2,3) 表示,自增列的第一個值是2,每次增加3,第二個值是5,第三個值是8,等等。當向表中插入數據行時,數據庫引擎自動向該列中插入唯一的,遞增的整數值。

<column_definition> ::= 
column_name <data_type>  [ NULL | NOT NULL ]
   IDENTITY [ ( seed ,increment ) ] [ NOT FOR REPLICATION ] 

2,屬性 ROWGUIDCOL               

屬性RowGUIDCol標識一個數據列是GUID列,數據表中可以有多個UniqueIdentifier類型數據列,但是每個表中只能有一個UniqueIdentifier數據列被標識為RowGUIDCol列。如果列被指定屬性RowGUIDCol,那么可以通過$ROWGUID引用,不需要通過列名來引用。

3,引用屬性標記的數據列

當訪問被屬性RowGUIDCol和Identity標記的數據列時,可以通過函數$RowGUID和$Identity來引用,不需要通過列名:

CREATE TABLE dbo.myTable_RowGUIDCol
(
    ColumnA uniqueidentifier ROWGUIDCOL not null
            constraint DF__myTable_RowGUIDCol_ColumnA DEFAULT NewID(),
    ColumnB int identity,
    columnC varchar(10)
) 

insert into dbo.myTable_RowGUIDCol(columnC)
values('test')

select $ROWGUID,$IDENTITY
from dbo.myTable_RowGUIDCol

二,顯式向自增列插入值

默認情況下,不能向IDENTITY列中插入數值。一般來說,在向數據表中插入新的數據行時,由數據庫引擎自動向自增列中插入唯一的,遞增的正整數值。

當想要手動向自增列中插入指定的數值,必須設置表的 Identity_Insert選項為ON。

SET IDENTITY_INSERT schema_name.table_name ON | OFF

1,啟用該選項時,必須注意:

  • 在插入數據值,必須在Insert子句中顯式指定Table的所有Column;
  • 如果插入值比當前的ID值大,那么SQL Server自動使用插入值作為新的ID值;
set IDENTITY_INSERT dbo.myTable_RowGUIDCol ON

insert into dbo.myTable_RowGUIDCol
(ColumnA,ColumnB,columnC)
values(newid(),3,'test2')

set IDENTITY_INSERT dbo.myTable_RowGUIDCol Off

insert into dbo.myTable_RowGUIDCol(columnC)
values('test3')

select ColumnA,ColumnB,columnC
from myTable_RowGUIDCol

2,創建示例數據

create table dbo.ta
(
id int identity(1,1) not null,
name varchar(10) null
)

insert into dbo.ta
values(1,'a')

出現錯誤: An explicit value for the identity column in table 'dbo.ta' can only be specified when a column list is used and IDENTITY_INSERT is ON.

2.1,將選項 IDENTITY_INSERT 設置為ON

set IDENTITY_INSERT dbo.ta on

2.2,顯式向ID列賦值

insert into dbo.ta
values(1,'a')

由於沒有在Insert子句中,顯式列出table的所有column,SQL Server Engine拋出錯誤:

An explicit value for the identity column in table 'dbo.ta' can only be specified when a column list is used and IDENTITY_INSERT is ON.

2.3,顯式列出Target Table的所有column

insert into dbo.ta(id,name)
values(1,'a')

三,RowGUIDCol 和 Identity 的比較

1,自增性

屬性Identity 標識的整數類型的Column 具有自動增長的特點,除非設置SET IDENTITY_INSERT ON,否者,不能顯式對自增列賦值。

RowGUIDCol屬性 用於標識UniqueIdentifier 列,唯一的作用是能夠使用$ROWGUID引用。沒有自動增長的特性,必須顯式賦值,或者創建Default 約束,使用默認值賦值。對UniqueIdentifier 列賦值有兩種方式:

  • 使用NewID(),NewSequentialID() 函數賦值;
  • 特定格式的字符串:‘xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx’,x是16進制數值,按照數字的位數,格式是:8-4-4-4-12,共32個數字,4個中划線;

2,“唯一”的范圍

在一個表中,ID列的值是唯一的,不同表的ID列的值可能相同;

如果使用NewID(),或 NewSequentialID() 函數賦值對UniqueIdentifier列賦值,那么在整個服務器內,所有UniqueIdentifier列的值是唯一的,即在同一個服務器的數據庫中,不同數據表的GUID列(使用NewID(),或 NewSequentialID() 函數賦值)的值是不相同的。

四,ID列的Not For Replication

Identity列的值是SQL Server Engine自動生成的,唯一的,遞增的整數值。默認情況下,用戶不能顯式插入數值。當啟用表的復制(Replication)時,ID列被復制/同步到其他訂閱表中,如何使兩個表的ID列值保持一致?SQL Server提供的做法是:在創建訂閱數據表時,為ID列指定 not for replication 屬性。當分發代理(distribution agent)執行Insert 命令時,ID列被顯式賦值,並且ID列的標識值不會自增,跟普通的整數列的行為相同。

在發布端中,雖然Identity列不需要指定Not For Replication屬性,但是,由於快照復制(Snapshot Replication)能夠把發布端(Publisher)中 Identity列的 not for replication屬性復制到Subscriber中,因此,建議在發布端中創建數據表時,為Identity列指定Not For Replication屬性。在事務復制中,如果沒有為ID列指定 not for replication 屬性,那么每次插入數據時,不管Insert 操作是失敗還是成功,其ID列的標識值都會自增

Not For Replication屬性有兩個作用:

  • 在事務復制中,Distribution能夠對Subscriber Table中的ID列賦值,保持兩個ID列數據的同步;
  • 在事務復制中,通過Distribution對Subscriber Table中的ID列賦值,該ID列的標識值不變;

如果顯式對ID列賦值,並且該值大於當前ID列的標識值,那么ID列的標識列變為該值;如果顯式對該表執行Insert操作,那么,ID列的標識值將增加。

例如,假如TableA的ID列名是EventID,該列具有not for replication屬性,

create table dbo.TableA
(
EventID int not null identity(1,1) not for replication , 
name
varchar(10) null
)

通過Replication同步到該列的最大值是100,但是該列的標識值不變,仍然是1。如果向該表中插入數據,那么,第一個ID值是1,第二個ID值是2,依次類推。

 

參考文檔:

IDENTITY (Property) (Transact-SQL)

NOTE 2----IDENTITY屬性字段上加上NOT FOR REPLICATION設置

Replicate Identity Columns


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM