來源:轉(zhuǎn)載 發(fā)布時間:2018-11-23 14:50:13 閱讀量:1029
外鍵約束的使用
在進(jìn)行多表查詢的時候,我們曾經(jīng)插入過一個非法的數(shù)據(jù)(臟數(shù)據(jù))是一個不合法的形式。當(dāng)然我們在之前的測試中是可以寫進(jìn)去的。證明了我們這個表中有這樣一個非法的數(shù)據(jù),這個數(shù)據(jù)破壞的數(shù)據(jù)的一致性原則,完整性就得不到保證。那怎么樣來得到保證呢,其實,我們可以通過外鍵約束來約束它。
外鍵約束(foreign key),這個外鍵的作用就可以保證我們這樣一個數(shù)據(jù)表的一致性和完整性。
也可以通過外鍵實現(xiàn)這種一對一,一對多的關(guān)系。
在這里,我們來看一下,外鍵相關(guān)的內(nèi)容。首先呢外鍵它是我們數(shù)據(jù)表的一個特殊字段。它可以參照我們的另一個表,我們叫做主表來創(chuàng)建一個我們這樣一個從表。想創(chuàng)建外鍵需要注意幾點(diǎn):1.只有innodb的存儲引擎支持外鍵。而且在創(chuàng)建外鍵的時候,我們的子表它必須是,字表的外鍵必須關(guān)聯(lián)我們父表的主鍵。
#測試外鍵
#那么外鍵呢,它是一個表參照另外一個表的主鍵來創(chuàng)建的
#創(chuàng)建一個新聞分類表,模擬這么一個cms系統(tǒng)news_cate
#新聞分類表
CREATE TABLE news_cate(
id TINYINT UNSIGNED AUTO_INCREMENT KEY,
cateName VARCHAR(50)NOT NULL UNIQUE,
cateDesc VARCHAR(100)NOT NULL DEFAULT ''
);
#新聞表news
CREATE TABLE news(
id INT UNSIGNED AUTO_INCREMENT KEY,
title VARCHAR(100)NOT NULL UNIQUE,
content VARCHAR(1000)NOT NULL,
cateId TINYINT UNSIGNED NOT NULL
);
#一定是先有分類,我們才能把新聞發(fā)布到指定的分類下
INSERT news_Cate(cateName)VALUES('國內(nèi)新聞'),
('國際新聞'),
('娛樂新聞'),
('體育新聞');
INSERT news(title,content,cateId)VALUES('a1','aaaa1',1),
('a2','aaaa2',1),
('a3','aaaa3',4),
('a4','aaaa4',2),
('a5','aaaa5',3);
#查詢new id title content
#news_cate cateName
SELECT n.id,n.title,c.cateName
FROM news AS n
#這里連接上另外一個表
JOIN news_cate AS c
#連接條件
ON n.`cateId`=c.`id`;
假設(shè)這么一種情況,新聞公司把國外新聞這一分類取消了,只報國內(nèi)新聞。
我們就可以看到這么一種情況,國際新聞這么一個類別已經(jīng)不存在了,但是在news這么一個表中,還存在著這么一條記錄。這合適嗎?
包括我們再來寫一個非法的數(shù)據(jù)。
#插入一個非法的記錄
INSERT news(title,content,cateId)VALUES('a6','aaaa6',45);
#首先我們看一下,有45這個分類嗎?沒有,都沒有這么一個分類,
#怎么能讓它插入成功呢,但是,SQL語句本身是沒有錯誤的。
這就是我們所說的一個臟數(shù)據(jù)。
#包括更嚴(yán)重的,我們直接把新聞分類表刪掉,
#我們可以看到這些新聞依然在這些分類下的
DROP TABLE news_cate;
SELECT *FROM news;
這合適嗎?顯然是不合適的,這時候就要用到我們的外鍵,它的作用就是保證數(shù)據(jù)的一致性和完整性。
創(chuàng)建外鍵的方式:1.在建表時指定外鍵:[constraint 外鍵名稱]foreign key (字段名稱)references 主表(字段名稱)
首先呢,在創(chuàng)建外鍵的時候我們應(yīng)該知道,我們的外鍵是依賴于主表的主鍵,所以說呢一定要先有主表。
那么什么叫主表呢?先有哪個,哪個就是主表,接下來創(chuàng)建外鍵的時候我們就會參照主表的主鍵來創(chuàng)建。
#測試外鍵
#那么外鍵呢,它是一個表參照另外一個表的主鍵來創(chuàng)建的
#創(chuàng)建一個新聞分類表,模擬這么一個cms系統(tǒng)news_cate
#新聞分類表
CREATE TABLE news_cate(
id TINYINT UNSIGNED AUTO_INCREMENT KEY,
cateName VARCHAR(50)NOT NULL UNIQUE,
cateDesc VARCHAR(100)NOT NULL DEFAULT ''
)ENGINE=INNODB;
#新聞表news
CREATE TABLE news(
id INT UNSIGNED AUTO_INCREMENT KEY,
title VARCHAR(100)NOT NULL UNIQUE,
content VARCHAR(1000)NOT NULL,
cateId TINYINT UNSIGNED NOT NULL,
#創(chuàng)建外鍵
FOREIGN KEY(cateId)REFERENCES news_cate(id)
)ENGINE=INNODB;
#一定是先有分類,我們才能把新聞發(fā)布到指定的分類下
外鍵類型要和主鍵類型一致。長度可以不同,但是類型要相同。
子表的外鍵字段和主表的主鍵字段類型要相似;如果是數(shù)值型,要求一致,并且無符號也要一致;如果是字符型,要求類型一致,長度可以不同。
創(chuàng)建外鍵后,會自動添加索引。
如果外鍵字段沒有主鍵,外鍵會自動添加主鍵。
INSERT news_Cate(cateName)VALUES('國內(nèi)新聞'),
('國際新聞'),
('娛樂新聞'),
('體育新聞');
INSERT news(title,content,cateId)VALUES('a1','aaaa1',1),
('a2','aaaa2',1),
('a3','aaaa3',4),
('a4','aaaa4',2),
('a5','aaaa5',3);
#測試刪除父表中的記錄 和刪除父表
DELETE FROM news_cate WHERE id=1;
UPDATE news_cate SET id=10 WHERE id=1;
INSERT news_cate(cateName)VALUES('教育新聞');
#對字表沒有影響的,修改是沒有問題的。
UPDATE news_cate SET cateName='教育' WHERE id=5;
UPDATE news_cate SET id=50 WHERE cateName='教育';
對字表沒有影響的,更新父表是可以的。
或者該分類下沒有內(nèi)容也是可以刪除的。
創(chuàng)建外鍵的時候,如果你沒有指定名字,系統(tǒng)會自動的幫你創(chuàng)建名字。
因為有外鍵的存在,父表是不讓你刪除的。
想把父表刪除,必須保證父表分類下沒有內(nèi)容。
這時呢你就可以看到外鍵的名稱是以你指定的名稱創(chuàng)建的。
---------------------
作者:weixin_40316053
來源:CSDN
原文:https://blog.csdn.net/weixin_40316053/article/details/84196072
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!