天天看點

列屬性: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      
列屬性:RowGUIDCol、Identity 和 not for replication

二,顯式向自增列插入值

預設情況下,不能向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      
列屬性:RowGUIDCol、Identity 和 not for replication

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

作者

:悅光陰

出處

:http://www.cnblogs.com/ljhdo/

本文版權歸作者和部落格園所有,歡迎轉載,但未經作者同意,必須保留此段聲明,且在文章頁面醒目位置顯示原文連接配接,否則保留追究法律責任的權利。

繼續閱讀