課本中把完整性約束單獨做成一章來講解,所以之前寫數據定義之基本表定義時說會放到后面講。
完整性約束有三種:實體完整性,參照完整性,用戶定義完整性。
最后會講完整性約束命名子句,所以一共四個部分。
Part [實體完整性]
實體完整性即主碼,用primary key定義。
可用兩種方式:
列級約束:create table test (id int primary key); 只能選取一列作為主碼;
表級約束:create table test (id int,name char(10),primary key(id,name)); 可選多列作為主碼;
Part [參照完整性]
參照完整性即外碼,用foreign key(<列名>[,<列名>...]) references <表名>(<列名>[,<列名>..]);而且只能使用表級約束。
現在以上面那個截圖中的表為參照,建立另一個表
注意:外碼一定參照主碼(可以是其他表的主碼,也可以時自己的),而且外碼的列數一定要等於被參照表的主碼列數。
參照完整性中比較麻煩的是違約處理,即當對被參照表進行update/delete/insert操作會破壞參照完整性時,參照表贏告訴被參照表應該怎么做。
所以參照表可以在定義外碼時添加上on delete/update [<no action> / <cascade>]。
看例子比較直觀:

其中no action 表示拒絕執行(為默認值),cascade表示級聯操作。
Part [用戶定義完整性]
書中的用戶定義完整性有三種:列值非空(not null),列值唯一(unique),列值需滿足條件表達式(check);
not null都是列級完整性約束,很好理解。
check和unique可以是列級,也可以是表級約束。
看例子很方便理解:
除了這三種,現在的sql產品中很多都支持一個設置默認值的操作(default);

如果不設置,默認為NULL(not null,primary key除外)。
Part [完整性約束命名子句]
完整性約束命名子句是用來給完整性約束命名,這樣我們就可以通過該名稱對完整性約束進行刪除、增加操作。
通過對mysql和sqlite的測試發現兩款產品對命名子句的支持很奇怪,所以這部分只供參考。
格式為:
constraint <完整性約束名> <完整性約束>
注意:通過測試發現mysql中只支持表級完整性約束命名子句,而sqlite都支持,但sqlite中對基本表的修改操作很有限(可見前面的帖子數據定義之基本表定義),所以基本沒什么用。
看例子很容易理解:

測試過程中發現,mysql中這樣定義沒有報錯,但constraint C1 check(id<100)並沒有起作用(消失了..),而且primary key也沒有被命名為Pkey。
過多的細節並沒有研究,希望有懂得的盆友給點指點。
上篇:視圖的創建、查詢與更新
