PRIMARY KEY主鍵和IDENTITY屬性函式的區別
1 PRIMARY KEY 約束
表通常具有包含唯一標識表中每一行的值的一列或一組列。這樣的一列或多列稱為表的主鍵 (PK),用於強制表的實體完整性。在建立或修改表時,您可以通過定義 PRIMARY KEY約束來建立主鍵。一個表只能有一個PRIMARY KEY 約束。如果已存在 PRIMARY KEY 約束,則可以修改或刪除它。例如,可以讓表的 PRIMARY KEY 約束引用其他列,更改列的順序、索引名、聚集選項或 PRIMARY KEY 約束的填充因子。但是,不能更改使用 PRIMARY KEY 約束定義的列長度。
注意: |
---|
若要修改 PRIMARY KEY 約束,必須先刪除現有的 PRIMARY KEY 約束,然後再用新定義重新建立該約束。 |
為表中的現有列新增 PRIMARY KEY 約束時,SQL Server 2005 Database Engine 將檢查現有列的資料和元資料以確保主鍵符合以下規則:
- 列不允許有空值。
建立表時指定的 PRIMARY KEY 約束列隱式轉換為 NOT NULL。 - 不能有重複的值。
如果為具有重複值或允許有空值的列新增 PRIMARY KEY 約束,則資料庫引擎 將返回一個錯誤並且不新增約束。
不能新增違反以上規則的 PRIMARY KEY 約束。
資料庫引擎 會自動建立唯一的索引來強制實施 PRIMARY KEY 約束的唯一性要求。如果表中不存在聚集索引或未顯式指定非聚集索引,則將建立唯一的聚集索引以強制實施 PRIMARY KEY 約束。
如果存在以下情況,則不能刪除 PRIMARY KEY 約束:
- 如果另一個表中的 FOREIGN KEY 約束引用了 PRIMARY KEY 約束,則必須先刪除 FOREIGN KEY 約束。
- 表包含應用於自身的 PRIMARY XML 索引。
一個表只能有一個 PRIMARY KEY 約束,並且 PRIMARY KEY約束中的列不能接受空值。由於 PRIMARY KEY 約束可保證資料的唯一性,因此經常對標識列定義這種約束。
如果為表指定了 PRIMARY KEY 約束,則 SQL Server 2005 Database Engine 將通過為主鍵列建立唯一索引來強制資料的唯一性。當在查詢中使用主鍵時,此索引還可用來對資料進行快速訪問。因此,所選的主鍵必須遵守的規則。
如果對多列定義了 PRIMARY KEY 約束,則一列中的值可能會重複,但來自 PRIMARY KEY 約束定義中所有列的任何值組合必須唯一。
(1) 在資料庫中建立主鍵:
在表設計器中,單擊要定義為主鍵的資料庫列的行選擇器。若要選擇多個列,請在單擊其他列的行選擇器時按住 Ctrl 鍵。
<//ddue.schemas.microsoft.com/authoring/2003/5:content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5"> <///ddue.schemas.microsoft.com/authoring/2003/5:content>右鍵單擊該列的行選擇器,然後選擇“設定主鍵”。此時,將自動建立名為“PK_”(後跟表名)的主鍵索引,您可以在“索引/鍵”對話方塊中看到該索引。
(2)使用SQL語句建立主鍵約束
使用SQL語句建立主鍵約束可以在建立表(Create Table)或修改表(Alter Table)時進行 建立。
在修改表中建立主鍵約束語法:
ALTER TABLE table_name
ADD
CONSTRAINT constraint_name
PRIMARY KEY [CLUSTERED | NONCLUSTERED]
{(Column[,…n])}
引數說明:
CONSTRAINT:建立約束的關鍵字。
constraint_name:建立約束的名稱。
PRIMARY KEY:表示所建立約束的型別為主鍵約束。
CLUSTERED | NONCLUSTERED:是表示為PRIMARY KEY或UNIQUE約束建立聚集或非聚集索引的關鍵字。PRIMARY KEY約束預設為CLUSTERED,UNIQUE約束預設為 NONCLUSTERED。
(3) 建表時建立PRIMARY KEY約束
CREATE TABLE mytable --建立表
(
USERID int CONSTRAINT pk_id PRIMARY KEY, --建立主鍵約束
USERNAME char (20), --資料列
)
說明:在上段程式碼中,CONSTRAINT pk_id PRIMARY KEY為建立一個主鍵約束,pk_id為使用者自定義的主鍵約束名稱,但名稱必須是合法的識別符號。
(4)新增PRIMARY KEY約束列
SQL語句如下:
ALTER TABLE mytable --修改表
ADD
CONSTRAINT pk_level
PRIMARY KEY CLUSTERED (userID)
GO --此時建立了一個pk_level聚集索引
說明:將某個資料列設定為主鍵約束時,該資料列不能為允許空,否則將會無法建立主鍵約束。
可以在查詢分析器中寫入如下程式碼將資料列設定為不允許空。
ALTER TABLE mytable --修改表
ALTER Column USERLEVEL char (2) NOT NUL --將USERLEVEL資料列設定為不允許空
(5) 刪除PRIMARY KEY主鍵約束
通過刪除主鍵約束來自動刪除由該主鍵約束創建出來的聚集索引
alter table t drop constraint pk_level
2 IDENTITY(屬性)(Transact-SQL)
在表中建立一個標識列。此屬性與 CREATE TABLE 及 ALTER TABLE Transact-SQL 語句一起使用。
以下示例將使用 IDENTITY
屬性,為自動遞增標識號建立一個新表
CREATE TABLE new_employees
(
id_num int IDENTITY(0,1), --從0開始每次都增加1
fname varchar (20),
minit char(1),
lname varchar(30)
)
3 IDENTITY(函式)(Transact-SQL)
只用於在帶有 INTO table 子句的 SELECT 語句中將標識列插入到新表中。
儘管類似,但是 IDENTITY函式不是與 CREATE TABLE 和 ALTER TABLE 一起使用的 IDENTITY 屬性。
因為該函式在表中建立一個列,所以必須用下列方式中的一種在選擇列表中指定該列的名稱:
--(1) SELECT IDENTITY(int, 1,1) AS ID_Num INTO NewTable FROM OldTable --(2) SELECT ID_Num =IDENTITY(int, 1, 1) --int型別從1開始每次增加1個 INTO NewTable FROM OldTable --方法1和方法2達到的效果是一樣的 |
4 資料庫表中欄位為主鍵並自增
1、把主鍵定義為自動增長識別符號型別(主要是SQL Server)
create table a1(id int identity(1,1) primary key not null, name varchar(15));
insert into a1(name) values('111'),('22');
select id from a1;
2、在MySQL 中,如果把表的主鍵設為auto_increment型別,資料庫就會自動為主鍵賦值。例如:
create table customers(id int auto_increment primary key not null, name varchar(15));
insert into customers(name) values("name1"),("name2");
select id from customers;
以上sql語句先建立了customers表,然後插入兩條記錄,在插入時僅僅設定了name欄位的值。最後查詢表中id欄位,查詢結果為:
id
1
2
由此可見,一旦把id設為auto_increment型別,mysql資料庫會自動按遞增的方式為主鍵賦值。
3 從序列中獲取自動增長的識別符號(主要是Oracle)
在Oracle中,可以為每張表的主鍵建立一個單獨的序列,然後從這個序列中獲取自動增加的識別符號,把它賦值給主鍵。例如一下語句建立了一個名為customer_id_seq的序列,這個序列的起始值為1,增量為2。
create sequence customer_id_seq increment by 2 start with 1
一旦定義了customer_id_seq序列,就可以訪問序列的curval和nextval屬性。
curval:返回序列的當前值
nextval:先增加序列的值,然後返回序列值
以下sql語句先建立了customers表,然後插入兩條記錄,在插入時設定了id和name欄位的值,其中id欄位的值來自於customer_id_seq序列。最後查詢customers表中的id欄位。
create table customers(id int primary key not null, name varchar(15));
insert into customers values(customer_id_seq.curval, "name1"),(customer_id_seq.nextval, "name2");
select id from customers;
如果在oracle中執行以上語句,查詢結果為:
id
1
3