
哈嘍,大家好!我是保護(hù)小周?,本期為大家?guī)?lái)的是 MySQL 數(shù)據(jù)庫(kù)中對(duì)表的約束,主要有null (空約束),unique(唯一約束),primary key(主鍵約束),default(默認(rèn)值約束), forelgn key(外鍵約束),check(檢查約束),超多實(shí)例講解,通俗易懂。
更多相關(guān)知識(shí)敬請(qǐng)期待:保護(hù)小周? *★,°*:.☆( ̄▽?zhuān)?/$:*.°★*

一、數(shù)據(jù)庫(kù)的約束
1.1數(shù)據(jù)庫(kù)的約束類(lèi)型

1.2 null 約束
我們?cè)趧?chuàng)建表的時(shí)候在創(chuàng)建字段的時(shí)候可以指定某列不為空,
設(shè)計(jì)一個(gè)學(xué)生表 stud ,包含字段 id 類(lèi)型 varchar(11) , 設(shè)置 not null , name 字段,類(lèi)型 varchar(20)

表創(chuàng)建成功,這是插入兩條記錄觀察一下:

我們可以觀察到 插入第一條數(shù)據(jù)時(shí),沒(méi)有報(bào)錯(cuò),當(dāng)?shù)诙l記錄企圖插入一條 null 值時(shí)就報(bào)錯(cuò)了。
Column 'id' cannot be null —— 列“id”不能為空

當(dāng)我們企圖插入 只有姓名的字段的是否也報(bào)錯(cuò)了,字段“id”沒(méi)有默認(rèn)值,也是就表示我們不能在id 為空的情況下插入一行記錄。show warnings; 可以查看當(dāng)前的sql語(yǔ)法錯(cuò)誤.
1.3 unique (唯一約束)
被指定的該列的記錄屬性不能重復(fù),比如:每一個(gè)人都有自己獨(dú)有的身份證號(hào),是獨(dú)一無(wú)二的數(shù)字組合,所以是不能重復(fù)的,在對(duì)字段添加該約束后,插入數(shù)據(jù)時(shí),會(huì)根據(jù)該字段約束遍歷表中的數(shù)據(jù),確認(rèn)沒(méi)有該字段重復(fù)值后方可插入。
設(shè)計(jì)一個(gè)學(xué)生表 stud ,包含字段 id 類(lèi)型 varchar(11) , 設(shè)置 unique約束 , name 字段 not null,類(lèi)型 varchar(20)

此時(shí)我們的 stud 表 id 字段的屬性不可重復(fù),name 字段屬性 不可為空。
插入3條記錄觀察觀察 : 1 張三, 1 ,李四 , 2, null;

Duplicate entry '1' for key 'id' —— 鍵“id”的重復(fù)條目“1”
Column 'name' cannot be null —— 列“name”不能為空

所以最終只插入了一條記錄。
1.4 primary key (主鍵約束)
有了約束之后,我們創(chuàng)建的表格就會(huì)越來(lái)越規(guī)范,根據(jù)博主上面所說(shuō),unique 約束字段不可重復(fù),
not null 約束字段不可為空,那這次介紹的 主鍵約束 primary key 相當(dāng)于 unique + not null 的約束效果,字段不為空且不可重復(fù)。

重新構(gòu)建了學(xué)生表 stud,并為 id 字段設(shè)置了主鍵約束,
插入3條記錄觀察觀察 : 1 張三, 1 ,李四 , 2, null;

Duplicate entry '1' for key 'PRIMARY' —— 鍵“PRIMARY”的重復(fù)條目“1”
Column 'name' cannot be null —— 列“name”不能為空
插入:null, 王五 或者 只插入 王五


一個(gè)數(shù)據(jù)表只能有一個(gè)主鍵,一個(gè)主鍵約束也可以針對(duì)多個(gè)字段創(chuàng)建約束,這樣就是多個(gè)字段處于不可為空且不可重復(fù)的狀態(tài)。,數(shù)據(jù)庫(kù)的主鍵,指的是一個(gè)列或多列的組合,其值能唯一地標(biāo)識(shí)表中的每一行,通過(guò)它可強(qiáng)制表的實(shí)體完整性。主鍵主要是用與其他表的外鍵關(guān)聯(lián),以及文本記錄的修改與刪除。
主鍵的作用
1)保證實(shí)體的完整性;
2)加快數(shù)據(jù)庫(kù)的操作速度
3)在表中添加新記錄時(shí),DBMS會(huì)自動(dòng)檢查新記錄的主鍵值,不允許該值與其他記錄的主鍵值重復(fù)。
4)DBMS自動(dòng)按主鍵值的順序顯示表中的記錄。如果沒(méi)有定義主鍵,則按輸入記錄的順序顯示表中的記錄。
對(duì)于整型(int)的主鍵,可以搭配自增長(zhǎng) auto_increment 使用,在插入數(shù)值時(shí),不給主鍵字段賦值,主鍵字段就會(huì)根據(jù)上一條主鍵字段的值 + 1。

插入2條記錄觀察觀察 : 1 張三, null ,李四 。

可以看到第一條數(shù)據(jù)我們對(duì)主鍵 id 插入了數(shù)值 1 , 第二條記錄,我們對(duì)主鍵 id 插入了數(shù)值 null ,正是因?yàn)槲覀儗?duì)整型主鍵 id 設(shè)置了自增長(zhǎng),所以根據(jù)上一個(gè)字段的 id 值自增 + 1 = 2;
再插入2條記錄觀察觀察 :100, 王五, null 趙六;

這個(gè)時(shí)候我們可以看到,這個(gè)自增屬性當(dāng)面對(duì)主動(dòng)插入時(shí)就會(huì)失效,當(dāng)需要自增時(shí)還是根據(jù)上一條記錄的自增字段的值 + 1,所以是趙六的學(xué)號(hào)是 101, 而不是 3,這個(gè)自增屬性就像是一個(gè)全局變量,可以記錄字段的值,輸入的時(shí)候就賦值,沒(méi)有賦值的是否就自增。
1.5 default (默認(rèn)值約束)
當(dāng)我們對(duì)某個(gè)字段定義 default 約束的時(shí)候,我們?cè)诓迦胗涗洉r(shí),如果忽略該條記錄,那么這條記錄會(huì)按照設(shè)置的默認(rèn)值填充。
例題:重新構(gòu)建了學(xué)生表 stud,并為 sex 字段設(shè)置了默認(rèn)值約束,默認(rèn)值設(shè)置為“男”。

數(shù)據(jù)表構(gòu)建完畢, 由上表可見(jiàn),博主設(shè)置了三個(gè)字段,id , name ,sex ,并將 sex 字段設(shè)置默認(rèn)值約束。
插入2條記錄觀察觀察 : 1 張三 男, 2 李四 。



第一次我們對(duì)第一行記錄的所有字段的數(shù)據(jù)進(jìn)行插入數(shù)據(jù),第二次我們只對(duì)第二行記錄的 id ,name 字段進(jìn)行設(shè)置,忽略了 sex 字段,但此時(shí)我們?cè)賹?duì)數(shù)據(jù)表 stud 的數(shù)據(jù)進(jìn)行查詢(xún)的時(shí)候發(fā)現(xiàn) 第二行記錄的sex 字段填充了我們?cè)O(shè)置的默認(rèn)值,男。
1.6 forelgn key (外鍵約束)
作為關(guān)系型數(shù)據(jù)庫(kù),外鍵約束在多表關(guān)系中是至關(guān)重要的,外鍵約束主要是關(guān)聯(lián)其他表的主鍵或者唯一值。語(yǔ)法:
foreign key 【字段名】references 【主表】(主鍵字段或者唯一字段)
重點(diǎn):
外鍵:針對(duì)子表,被約束的字段數(shù)據(jù),受父字段數(shù)據(jù)的約束,不可以增改。
外鍵:針對(duì)父表,不能刪除修改子表被約束的字段,兩表之間約束是雙向的。
舉個(gè)例字:

我們先創(chuàng)建這兩張表并為成績(jī)表建立外鍵約束。
學(xué)生表 stud 的創(chuàng)建:

成績(jī)表 score 的創(chuàng)建:

對(duì)子表score 的id 字段與 學(xué)生表的id字段產(chǎn)生了外鍵約束, 學(xué)生表為主表。
例題: 對(duì)stud 學(xué)生表插入數(shù)據(jù),觀察對(duì)score 成績(jī)表有什么影響?
1 張三 男, 2 李四 男 , 3 王小六 女

語(yǔ)句正常執(zhí)行沒(méi)有任何變化。
例題: 對(duì)score 成績(jī)表插入數(shù)據(jù),觀察對(duì)stud 學(xué)生表有什么影響?
1 80 99 90, 2 74 80 99 , 3 98 78 69 , 4 50 65 56

當(dāng)我們插入前三條數(shù)據(jù)的時(shí)候沒(méi)有任何問(wèn)題,現(xiàn)在插入第四條數(shù)據(jù)

直接報(bào)錯(cuò),不必驚慌,錯(cuò)誤1452(23000):不能添加或更新子行:外鍵約束失敗(' school ')。' score_ibfk_1 ',約束' score_ibfk_1 '外鍵(' sc_id ')
這是報(bào)錯(cuò)信息,意思就是我們不能添加子行,因?yàn)槭艿搅酥鞅?stud, stu_id 字段的約束,
外鍵:針對(duì)子表,被約束的字段數(shù)據(jù),受父字段數(shù)據(jù)的約束,不可以增改(改也只能是修改非約束字段)。通俗來(lái)講就是在添加數(shù)據(jù)或者是修改數(shù)據(jù)之前,會(huì)先遍歷父表,如果在父表中找不到約束的關(guān)鍵字,就不允許在子表中進(jìn)行 insert / update 操作。
所以我們不能在成績(jī)表中添加學(xué)號(hào)不在 stud學(xué)生表中的信息,在創(chuàng)建成績(jī)表的時(shí)候我們也對(duì) sc_id 字段設(shè)置了主鍵約束,所以呢, 要想在成績(jī)表中添加記錄需要滿(mǎn)足以下要求,該記錄 sc_id 字段不可為空且不可重復(fù)且該記錄中的 sc_id字段值必須在 stud 學(xué)生表中存在。
此時(shí)我們成績(jī)表的操作并不會(huì)對(duì)我們的主表造成影響。
例題: 對(duì) stud 學(xué)生表刪除數(shù)據(jù)修改數(shù)據(jù),觀察對(duì) score 成績(jī)表有什么影響?
先嘗試刪除 學(xué)生表中的一條記錄:

錯(cuò)誤1451(23000):不能刪除或更新父行:外鍵約束失敗(' school ')。' score_ibfk_1 ',約束' score_ibfk_1 '外鍵(' sc_id ')
報(bào)錯(cuò)提示的也非常明顯,我們不能修改或刪除父行, 因?yàn)閮杀碇g存在外鍵約束。
外鍵:針對(duì)父表,不能刪除修改子表被約束的字段,兩表之間約束是雙向的。
嘗試修改學(xué)生表中的一條記錄:將學(xué)生表中的學(xué)號(hào)為3 的同學(xué)的學(xué)號(hào)修改為 4

錯(cuò)誤1451(23000):不能刪除或更新父行:外鍵約束失敗(' school ')。' score_ibfk_1 ',約束' score_ibfk_1 '外鍵(' sc_id ')
嘗試修改學(xué)生表中的一條記錄:將學(xué)生表中的學(xué)號(hào)為3 的同學(xué)姓名由 王小六 修改為 王六

修改成功,只要不修改作為外鍵約束的字段,其他字段的值是可以被修改的。
總結(jié):兩表之間或者多表之間存在外鍵約束,作為主表來(lái)講是不可以隨便刪除記錄的, 那么如何保證數(shù)據(jù)的有效性呢,比如張三同學(xué)已經(jīng)畢業(yè)了,那張三同學(xué)的信息就失效了。我們有兩種做法,
一:是刪除所有與主表與子表有對(duì)應(yīng)字段外鍵關(guān)系的記錄,主表是不可刪除修改,子表是可以刪除的, 我們先將子表中的約束記錄刪除,主表中的約束字段沒(méi)有在子表中體現(xiàn),那么主表中自然是允許刪除的,但是有一個(gè)缺點(diǎn)就是你無(wú)法判斷該字段建立了多少外鍵約束,非要?jiǎng)h除的話,需要去找到這些子表,子表與子表之間有可能也存在外鍵約束,就會(huì)非常的復(fù)雜。
二:對(duì)主表添加可以判斷數(shù)據(jù)是否有效的字段,比如是否畢業(yè),當(dāng)張三畢業(yè)時(shí),我們將該字段設(shè)置為已畢業(yè),然后再使用數(shù)據(jù)時(shí)是可以添加條件來(lái)約束,例如查找有所未畢業(yè)同學(xué)的信息,利用條件查詢(xún)即可。
1.7 check 檢查約束
在數(shù)據(jù)庫(kù)中,CHECK 約束是指約束表中某一個(gè)或者某些列中可接受的數(shù)據(jù)值或者數(shù)據(jù)格式。
CHECK 約束可以應(yīng)用于一個(gè)或者多個(gè)列,也可以將多個(gè)CHECK 約束應(yīng)用于一個(gè)列。
當(dāng)除去某個(gè)表時(shí),對(duì)這個(gè)表的CHECK 約束也將同時(shí)被去除。
在更新表數(shù)據(jù)的時(shí)候,系統(tǒng)會(huì)檢查更新后的數(shù)據(jù)行是否滿(mǎn)足 CHECK 約束中的限定條件。MySQL 可以使用簡(jiǎn)單的表達(dá)式來(lái)實(shí)現(xiàn) CHECK 約束,也允許使用復(fù)雜的表達(dá)式作為限定條件,例如在限定條件中加入子查詢(xún)。
設(shè)置檢查約束時(shí)要根據(jù)實(shí)際情況進(jìn)行設(shè)置,這樣能夠減少無(wú)效數(shù)據(jù)的輸入。
這個(gè)約束是啥意思呢,就是指定字段中的數(shù)據(jù)只能存在于設(shè)定的數(shù)據(jù)范圍內(nèi),例如:sex 字段 ,
check (sex = "男" or sex = "女")
我們這樣限定了之后,就不會(huì)出現(xiàn)其他的性別,比如說(shuō),"雙性",不可能輸入,只能存在 “男”或 “女”。比如我們限定了學(xué)號(hào)的范圍 [1,10], 我們的id就只能在這個(gè)范圍內(nèi)。

表創(chuàng)建完畢,現(xiàn)在插入兩條數(shù)據(jù)觀察觀察。


但是我們會(huì)發(fā)現(xiàn)雖然我們期望 check 約束可以將數(shù)據(jù)限定來(lái)我們期望的范圍內(nèi),但是在添加數(shù)據(jù)的時(shí)候還是可以超出這個(gè)限制,原因是因?yàn)?不同于SQL,在MYSQL中,CHECK只是一段可調(diào)用但無(wú)意義的子句。MySQL會(huì)直接忽略。 CHECK子句會(huì)被分析,但是會(huì)被忽略。
說(shuō)白了就是沒(méi)用,就是個(gè)擺爛的,博主尋思以為自己寫(xiě)錯(cuò)了,特意查詢(xún)了一波資料,啥用沒(méi)有,咦~
二、修改表的結(jié)構(gòu) (alter)
以上約束,可以看到博主都是在創(chuàng)建表的時(shí)候添加的( create ),除了我們?cè)趧?chuàng)建的時(shí)候添加約束,其實(shí)還有一種辦法就是 修改表的結(jié)構(gòu) (alter),但是不建議使用吖,因?yàn)楫?dāng)我們對(duì)已有的表再去修改表的結(jié)構(gòu)的時(shí)候會(huì)對(duì)表中原先存儲(chǔ)的數(shù)據(jù)造成一定程度上的影響,那么我們要添加約束的時(shí)候使用修改字段的這個(gè)關(guān)鍵字即可 ,就像是創(chuàng)建時(shí)的那樣,類(lèi)型后面加上約束。
- 修改字段
ALTER TABLE test.student MODIFY id_card varchar(30) 【約束】
-- 修改表結(jié)構(gòu)
-- 添加字段
-- 新增一個(gè)叫做id_card的字段,它的類(lèi)型是可變字符串且非空。
ALTER TABLE test.student ADD id_card varchar(18) NOT NULL;
-- 修改字段
ALTER TABLE test.student MODIFY id_card varchar(30)
-- 修改字段名
ALTER TABLE test.student CHANGE id_card id_card1 char(10) not null;
-- 刪除字段
ALTER TABLE test.student DROP id_card1;
-- 修改表名
ALTER TABLE test.student RENAME test.stu;
好了好了,關(guān)于數(shù)據(jù)庫(kù)的約束就淺淺的說(shuō)一一下啦,關(guān)于查詢(xún)還有許多知識(shí),一篇寫(xiě)不下,下篇博客將著重點(diǎn)將查詢(xún)的進(jìn)階~
至此,Mysql 系列的第四篇內(nèi)容博主已經(jīng)分享完了,希望對(duì)大家有所幫助,如有不妥之處歡迎批評(píng)指正。

本期收錄于博主的專(zhuān)欄—— MySQL & JDBC,適用于編程初學(xué)者,感興趣的朋友們可以訂閱,查看其它“MySQL 數(shù)據(jù)庫(kù)以及Java JDBC 編程的相關(guān)知識(shí)”。
下一期:MySQL 數(shù)據(jù)庫(kù)查詢(xún)的進(jìn)階
感謝每一個(gè)觀看本篇文章的朋友,更多精彩敬請(qǐng)期待:保護(hù)小周? *★,°*:.☆( ̄▽?zhuān)?/$:*.°★* 文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-407449.html
遇見(jiàn)你,所有的星星都落在我的頭上……文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-407449.html
到了這里,關(guān)于【MySQL】數(shù)據(jù)庫(kù)的約束的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!