標籤:style blog color io 使用 strong ar for 資料
一、約束的分類
在SQLServer中,有3種不同類型的約束。
1、實體約束
實體約束是關於行的,比如某一行出現的值就不允許出現在其他行,例如主鍵。
2、域約束
域約束是關於列的,對於所有行,某一列有那些約束,例如CHECK約束。
3、參照完整性條件約束
如果某列的值必須與其他列的值匹配,那就意味著需要一個參照完整性條件約束,例如外鍵。
二、約束命名
在學習約束之前,首先來瞭解下為約束命名需要注意哪些地方。
SQLServer在我們不提供名稱時,會自動建立名稱,但是由系統自動建立的名稱並不是特別有用。
例如,系統產生的主鍵名稱可能是這樣的:PK_Employees_145C0A3F。
PK代表主鍵(primary key),Employees代表在Employees表中,而剩下的“145C0A3F”部分是為了保證唯一性而隨機產生的值。只有通過指令碼建立才會得到這種值,如果是通過Managerment Studio建立表,那麼就直接是PK_Employees。
對於系統自動產生的Check約束名稱如:CK_Customers_22AA2996。CK代表這是一個Check約束,Customers代表是在Customers表中,後面的22AA2996還是一個隨機數。如果一個表中有多個Check約束,則命名可能如下:
CK_Customers_22AA2996
CK_Customers_25869641
CK_Customers_267ABA7A
如果你需要修改這些約束其中的一個,那麼你很難分辨這些約束到底是哪一個。
因此,為了能夠一眼看上去就知道這個約束是用來幹什麼的,我們應該使用一種簡單明了的短語來進行命名。
例如要確保某一列電話號碼格式正確的約束,我們可以使用命名CK_Customers_PhoneNo這樣的短語來命名。
總之命名要做到以下幾點:
1、一致性
2、通俗易懂
3、滿足以上兩個條件的情況下簡化名稱。
三、鍵約束1、
主鍵約束
主鍵是每行的唯一識別碼,僅僅通過它就能準確定位到一行,其中主鍵列在整個表中不能有重複,必須包含唯一的值(不能為NULL)。由於主鍵在關聯式資料庫中的重要性,因此它是所有鍵和約束中最重要的。
下面來說說主鍵的建立方式
1、在建立表的時候建立主鍵約束。
create table customer( customerId int identity not null primary key, --建立主鍵約束 CustomerName nvarchar(30) not null);
怎麼樣,非常簡單吧!
2、在已存在的表上建立主鍵約束
現在假設已經存在了一張表,但是還沒有主鍵約束:
alter table person add constraint PK_Employee_Id --外鍵名稱 primary key(personId) --personId 欄位名
alter名稱告訴SQLServer如下資訊:
1、添加了一些內容到表中(也可以刪除表中的某些內容)
2、添加了什麼內容(一個約束)
3、對約束的命名(允許以後直接存取約束)
4、約束的類型(主鍵約束)
5、約束應用於哪個列。
3、複合主鍵的建立
如果實在Management Studio中,建立複合主鍵,只需要按住Ctrl鍵,選中兩個列,然後設定為主鍵就OK了,非常簡單。下面主要講述使用T-SQL建立複合主鍵的方法:
ALTER TABLE 表名 WITH NOCHECK ADD CONSTRAINT [PK_表名] PRIMARY KEY NONCLUSTERED ( [欄位名1], [欄位名2] )
在多對多聯絡中,常常會有一張表來描述其他兩張表的關係,就以此讀者和書為例子:
ALTER TABLE ReaderAndBook ADD CONSTRAINT [PK_ReaderAndBook] PRIMARY KEY NONCLUSTERED ( ReaderId, BookId )
2、外鍵約束
外鍵既能確保資料完整性,也能表現表之間的關係。添加了外鍵之後,插入參考資料表的記錄要麼必須被參考資料表中被引用列的某條記錄匹配,要麼外鍵列的值必須設定為NULL。
外鍵和主鍵不一樣,每個表中的外鍵數目不限制唯一性。在每個表中,每一有-~253個外鍵。唯一的限制是一個列只能引用一個外鍵。一個列可以被多個外鍵引用。
1、建立表的時候建立外鍵
create table orders( orderId int identity not null primary key, customerId int not null foreign key references customer(customerId) --約束類型-外鍵-參考資料表(列名));
2、在已存在的表中添加一個外鍵
假設上面的代碼去掉了添加外鍵行,那麼可以書寫代碼如下:
alter table orders add constraint FK_Orders_CustomerId --添加約束 名稱 foreign key (customerId) references customer(customerId) --外鍵約束,外鍵列名,被引用列名
剛添加的約束和之前添加的約束一樣生效,如果某行引用customerId不存在,那麼就不允許把該行添加到Orders表中。
3、級聯動作
外鍵和其他類型鍵的一個重要區別是:外鍵是雙向的,即不僅是限制子表的值必須存在於父表中,還在每次對父表操作後檢查子行(這樣避免了孤行)。SQLServer的預設行為是在子行存在時“限制”父行被刪除。然而,有時會自動刪除任何依賴的記錄,而不是防止刪除被引用的記錄。同樣在更新記錄時,可能希望依賴的記錄自動引用剛剛更新的記錄。比較少見的情況是,你可能希望將引用行改變為某個已知的狀態。為此,可以選擇將依賴行的值設定為NULL或者那個列的預設值。
這種進行自動刪除和自動更新的過程稱為級聯。這種過程,特別是刪除過程,可以經過幾層的以來關係(一條記錄依賴於另一條記錄,而這另一條記錄又依賴其他記錄)。在SQLServer中實現級聯動作需要做的就是修改外鍵文法-只需要在添加前面加上ON子句。例如:
alter table orders add constraint FK_Orders_CustomerId --添加約束 名稱 foreign key (customerId) references customer(customerId) --外鍵約束,外鍵列名,被引用列名 on update no action --預設 修改時不串聯更新子表 on delete cascade --刪除時串聯刪除依賴行
當在進行串聯刪除時,如果一個表級聯了另一個表,而另一個表又級聯了其他表,這種級聯會一直下去,不受限制,這其實是級聯的一個危險之處,很容易一個不小心刪掉大量資料。
級聯動作除了no action,cascade之外,還有set null和set default。後兩個是在SQLServer2005中引入的,如果要相容到SQLServer2000的話,要避免使用這兩個級聯動作。但是他們的才做是非常簡單的:如果執行更新而改變了一個父行的值,那麼子行的值將被設定為NULL,或者設定為該列的預設值(不管SET NULL還是SET DEFAULT)。
4、外鍵其他方面的考慮
外鍵中的之只有相中可能的選擇:
1、在列中填充與被參考資料表中的相應列相匹配的值。
通過定義引用列為NOT NULL,可以使外鍵完全是必須的(即使用者添加資料時必須參考資料表中必須有相匹配的一行資料)。
2、不填充任何值,而使該值為NULL。
允許引用列有NULL值時,使用者可以選擇不提供值-即使在被參考資料表沒有與NULL值匹配的行,還是允許插入。
3、唯一約束
唯一約束與主鍵比較相似,共同點在於它們都要求表中指定的列(或者列的組合)上有一個唯一值,區別是唯一約束沒有被看作表中記錄的唯一識別碼(即使你可以按這樣的方式使用也有效),而且可以有多個唯一約束(而在每個表中只能有一個主鍵)。
一旦建立了唯一約束,那麼指定列中的每個值必須是唯一的。如果更新或者插入一條記錄在帶唯一約束的列上有已經存在的值的記錄,SQLServer將拋出錯誤,拒絕這個記錄。
和主鍵不同,唯一約束不會自動防止設定一個NULL值,是否允許為NULL由表中相應列的NULL選項的設定決定,但即使確實允許NULL值,一張表中也只能夠插入一個NULL值(如果允許多個,那就不叫唯一了)。
在已存在的表上建立唯一約束:
alter table Account add constraint AK_AccountName --約束名 unique (Account_Name) -- 列名
AK代表替換鍵(Alternate Key),唯一約束也叫替換鍵。
主鍵和唯一約束的區別:
- 主鍵約束不允許出現NULL值。任何索引的索引鍵都不允許包含null值。但唯一約束允許包含NULL值,但唯一約束把兩個NULL值當作重複值,所以施加了唯一約束的每一列只允許包含一個NULL值。
- 建立主鍵時會自動建立叢集索引,除非當前表中已經含有了叢集索引或是建立主鍵時指定了NONCLUSTERED關鍵字。
- 建立唯一約束時會自動建立非叢集索引,除非你指定了CLUSTERED關鍵字並且當前表中還沒有叢集索引。
- 每個表中只能有一個主鍵,但可以由多個唯一約束。
SQLServer - 約束