來源:一個程序渣渣的小后院 發(fā)布時(shí)間:2018-12-05 11:38:50 閱讀量:1241
關(guān)系完整性是對關(guān)系的某種約束,當(dāng)關(guān)系隨著時(shí)間變化(增刪改等操作改變數(shù)據(jù)庫關(guān)系表)時(shí)應(yīng)該滿足一定的約束條件,通常這些約束條件都依賴于客觀事實(shí)
關(guān)系完整性包含三個方面,分別是
實(shí)體完整性
參照完整性
用戶自定義完整性
其中實(shí)體完整性和參照完整性是關(guān)系模型必須滿足的約束條件,或者說是所有數(shù)據(jù)庫管理系統(tǒng)都自動支持的約束條件。而用戶自定義完整性則是根據(jù)不同的應(yīng)用程序(不同的使用場景)有選擇的設(shè)置的一些約束條件
實(shí)體完整性
實(shí)體完整性實(shí)際上就是對于主鍵完整性的約束條件,要求主鍵不能為空(NULL)。如果主鍵為空,那么就無法達(dá)到唯一標(biāo)識一個實(shí)體的目的了,所以實(shí)體完整性應(yīng)該包含兩個約束
不能為NULL
必須唯一,不能重復(fù)
實(shí)體完整性在SQL語句中使用PRIMARY KEY關(guān)鍵字定義(實(shí)際上就是在定義主鍵)。有兩種定義方式,一種是在定義屬性的時(shí)候?qū)RIMARY KEY添加到后面,另一種是在定義完所有屬性之后使用關(guān)鍵字PRIMARY KEY指出
下面的例子創(chuàng)建一個student表,并將學(xué)生id設(shè)置為主鍵(用來設(shè)置實(shí)體完整性約束)
CREATE TABLE student (
id INT PRIMARY KEY, /* 緊跟在屬性定義后面 */
name VARCHAR(20) NOT NULL,
sex ENUM('male', 'female'),
age INT NOT NULL
);
1
2
3
4
5
6
或者
CREATE TABLE student (
id INT,
name VARCHAR(20) NOT NULL,
sex ENUM('male', 'female'),
age INT NOT NULL ,
PRIMARY KEY(id) /* 在定義完所有屬性后設(shè)置主鍵 */
);
1
2
3
4
5
6
7
另外,考慮另一個表student_course,它存儲著所有學(xué)生的選課信息,只包含學(xué)生id和課程id兩個屬性,那么根據(jù)客觀事實(shí)可知,想要唯一確定這個表中的某一行,就必須同時(shí)提供學(xué)生id和課程id,也就是說student_course由(學(xué)生id,課程id)這個二元組唯一確定,所以它的主鍵應(yīng)該包含兩個屬性
需要注意的是,當(dāng)主鍵包含多個字段時(shí),只能采用上述第二種方式定義主鍵,對于student_course的表定義如下
CREATE TABLE student_course (
student_id INT NOT NULL,
course_id INT NOT NULL,
PRIMARY KEY(student_id, course_id) /* 在所有屬性定義完后定義主鍵 */
);
1
2
3
4
5
設(shè)置之后,當(dāng)向student表插入數(shù)據(jù)時(shí),就必須提供一個獨(dú)一無二的學(xué)生id,任何將學(xué)生id設(shè)置為NULL或者提供了一個重復(fù)的id的操作都會報(bào)錯
參照完整性
參照完整性是相對于外鍵而言的,在數(shù)據(jù)庫中,外鍵常用來關(guān)聯(lián)兩個表,它的值要么為NULL,要么就是它參照的那個表的主鍵值。以社交網(wǎng)絡(luò)系統(tǒng)中的用戶實(shí)體和分組實(shí)體為例,其中
用戶實(shí)體定義了一個用戶的各種信息,包括
用戶id
密碼
個人信息等
好友分組實(shí)體定義了一個分組的信息,包括
分組id
分組名
用戶id
這樣在查找每個用戶的所有分組時(shí)只需要將兩個表進(jìn)行聯(lián)結(jié)并且選擇用戶表的用戶id等于分組表的用戶id的那幾行即可
在上面的設(shè)計(jì)中,好友分組包含了用戶id,它是用戶表的主鍵,像這樣的屬性被稱為外鍵,它由FOREIGN KEY … REFERENCES關(guān)鍵字定義
CREATE TABLE user (
user_id INT AUTO_INCREMENT PRIMARY KEY,
password VARCHAR(20) NOT NULL,
);
CREATE TABLE groups (
group_id INT AUTO_INCREMENT,
group_name VARCHAR(20) NOT NULL,
user_id INT,
PRIMARY KEY(group_id, group_name),
FOREIGN KEY (user_id) REFERENCES user(user_id)
/* 將user_id定為外鍵,參照user表中的user_id屬性 */
);
1
2
3
4
5
6
7
8
9
10
11
12
13
對于外鍵的約束實(shí)際上就是對于參照完整性的約束,對于上面的示例而言,groups表中的user_id字段必須在user表中的user_id字段中存在,也就是不能出現(xiàn)在groups中存在一個user_id它在user中沒有的情況
當(dāng)對表進(jìn)行插入刪除時(shí),數(shù)據(jù)庫管理系統(tǒng)會自動檢測該約束規(guī)則,常見的情況有兩種
向groups表中插入/更新了一行數(shù)據(jù),其中的user_id不是user中的數(shù)據(jù),就會報(bào)錯
將user中的某一行數(shù)據(jù)刪除/更新,而groups中存在將要被刪除/更新那一行的user_id的數(shù)據(jù),則操作被拒絕,同樣會報(bào)錯
上述的兩種情況被稱為發(fā)生了不一致,數(shù)據(jù)庫管理系統(tǒng)有以下幾種方式可以處理這種問題
拒絕執(zhí)行(NO ACTION),不允許這種情況發(fā)生,一旦發(fā)送,則會報(bào)錯
級聯(lián)操作(CASCADE),當(dāng)刪除或更新user表導(dǎo)致發(fā)生不一致時(shí),會刪除或更新groups表將不一致消除
設(shè)置為空值,代替級聯(lián)對groups表的刪除和更新操作,將不一致的外鍵值設(shè)置為NULL
對于級聯(lián)操作,首先重新定義groups表,為外鍵user_id設(shè)置級聯(lián)
CREATE TABLE groups (
group_id INT AUTO_INCREMENT,
group_name VARCHAR(20) NOT NULL,
user_id INT,
PRIMARY KEY(group_id, group_name),
FOREIGN KEY (user_id) REFERENCES user(user_id) ON DELETE CASCADE
/* 表示當(dāng)user表的某個user_id被刪除后,級聯(lián)刪除掉groups表對應(yīng)數(shù)據(jù) */
);
1
2
3
4
5
6
7
8
然后為兩個表添加數(shù)據(jù)
mysql> SELECT * FROM user;
+---------+----------+
| user_id | password |
+---------+----------+
| 1 | 1234567 |
| 2 | 1234567 |
| 3 | 1234567 |
+---------+----------+
mysql> SELECT * FROM groups;
+----------+------------+---------+
| group_id | group_name | user_id |
+----------+------------+---------+
| 1 | 1_group1 | 1 |
| 1 | 1_group2 | 1 |
| 1 | 1_group3 | 1 |
| 2 | 2_group1 | 2 |
+----------+------------+---------+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
現(xiàn)在執(zhí)行刪除操作,刪除user表中user_id為1的元組,然后查看groups表,發(fā)現(xiàn)和user_id相關(guān)的數(shù)據(jù)也全部被刪除
mysql> DELETE FROM user WHERE user_id = 1;
Query OK, 1 row affected (0.02 sec)
mysql> SELECT * FROM groups;
+----------+------------+---------+
| group_id | group_name | user_id |
+----------+------------+---------+
| 2 | 2_group1 | 2 |
+----------+------------+---------+
1
2
3
4
5
6
7
8
9
用戶自定義完整性
在CREATE TABLE中定義屬性時(shí),可以根據(jù)應(yīng)用程序的要求在屬性上添加約束條件,即屬性限制,包括
列值非空(NOT NULL)
列值唯一(UNIQUE)
檢查列值是否滿足一個條件表達(dá)式(CHECK短語)
比如上述用戶表中的密碼password屬性,很顯然不應(yīng)該允許用戶不設(shè)置密碼,所以在定義這個屬性的時(shí)候會加上NOT NULL約束
對于CHECK短語,它可以定義在單個屬性之后,也可以在所有屬性定義完成后再定義,如果是后者,那么條件表達(dá)式可以使用任意多個屬性進(jìn)行判斷
---------------------
作者:一個程序渣渣的小后院
來源:CSDN
原文:https://blog.csdn.net/sinat_35261315/article/details/80561832
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!