概念:
為了保證數(shù)據(jù)的完整性和一致性,MySQL提供了約束這個屬性笤受。約束分為表級約束和列級約束,如果約束只是針對某一個字段來說敌蜂,則稱之為列級約束箩兽,如果針對兩個或者兩個以上的,則稱之為表級約束章喉。列級約束既可以在列定義時聲明汗贫,也可以在列定義后聲明,而表級約束只能在列定義后聲明秸脱。
約束類型包括以下幾種:
NOT NULL (非空約束)
PRIMARY KEY (主鍵約束)
UNIQUE KEY (唯一約束)
DEFAULT (默認約束)
FOREIGN KEY (外鍵約束)
場景:
在操作數(shù)據(jù)表時落包,為了避免插入重復(fù)的數(shù)據(jù),可以在字段后面添加 AUTO_INCREMENT(自動編號) 屬性來保證記錄的唯一性摊唇,并且該字段必須為整型或者字符型咐蝇,若使用字符型,小數(shù)必須為 0 遏片。
該屬性如下特點:
⑴ 賦予自動編號屬性的字段必須定義為主鍵
⑵ 在默認情況下嘹害,起始值為1,每次遞增加1
案例:
創(chuàng)建一張 tb_test2 數(shù)據(jù)表吮便,并且給 id 字段賦予 AUTO_INCREMENT 屬性笔呀,系統(tǒng)報錯,根據(jù)信息可以看出髓需,字段 id 必須設(shè)置為主鍵许师。接下來我們來了解一下主鍵約束和其他約束。(非空約束在上一文結(jié)尾已提及)
1僚匆、主鍵約束 (PRIMARY KEY)
特點:
⑴ 每張數(shù)據(jù)表只能存在一個主鍵
⑵ 主鍵可以保證記錄的唯一性
⑶ 主鍵自動默認為 NOT NULL
案例:
以剛才創(chuàng)建的表為例微渠,重新創(chuàng)建數(shù)據(jù)表,在 id 后添加 PRIMARY KEY 屬性表示該字段為主鍵咧擂。
接著查看數(shù)據(jù)表的結(jié)構(gòu):
可以發(fā)現(xiàn)逞盆,字段 id 不為 NULL 符合 AUTO_INCREMENT 屬性特點,key 的值為 PRI松申,說明該字段為主鍵云芦,而 username 在創(chuàng)建時已經(jīng)指定為 NOT NULL 。當(dāng)我們依次插入數(shù)據(jù)時贸桶,對應(yīng)的id 會自動增長舅逸。
案例:(數(shù)據(jù)表的記錄操作會在后續(xù)的文章提及)
依次插入三條記錄,并查看所有記錄皇筛,數(shù)據(jù)表的 id 自動遞增琉历。
注: AUTO_INCREMENT 必須和 PRIMARY KEY 一起使用,而 PRIMARY KEY 不一定和
AUTO_INCREMENT 一起使用。
案例:
當(dāng)我們創(chuàng)建數(shù)據(jù)表并沒有給主鍵 id 賦予 AUTO_INCREMENT 時旗笔,系統(tǒng)提示創(chuàng)建成功彪置,此時的 id 不能為空,查詢表結(jié)構(gòu)可以看出 Extra 字段沒有 auto_increment 屬性换团。我們插入一些記錄來驗證一下:
在插入記錄時悉稠,分別對 id 和 username 字段進行賦值,但是不允許插入兩條相同的記錄:
當(dāng)我們插入相同 id 的記錄時艘包,系統(tǒng)報錯的猛,提示表已存在該記錄。
在一張數(shù)據(jù)表中想虎,除了主鍵約束外卦尊,為了保證記錄的唯一性,MySQL 提供了另一種約束舌厨,
就是唯一約束岂却。
2、唯一約束 (UNIQUE KEY)
特點:
⑴ 唯一約束可以保證記錄的唯一性
⑵ 唯一約束的字段可以為空值(NULL)
⑶ 每張數(shù)據(jù)表可以存在多個唯一約束
當(dāng)然了裙椭,對于指定唯一約束的字段來說躏哩,如果插入的多條記錄都為空,表里也只存在一條空記錄揉燃,保證唯一性扫尺。
案例:
創(chuàng)建表 tb_test4 ,字段 id 為主鍵且自動增長炊汤,username 為字符型且唯一約束正驻。
我們插入記錄驗證一下:
插入一條記錄提示成功。
重新插入一條相同的記錄抢腐,系統(tǒng)報錯姑曙,不能重復(fù)添加,說明 username 被賦予唯一約束迈倍,只能插入一條記錄伤靠。
3、默認約束 (DEFAULT)
特點:
當(dāng)插入記錄時啼染,如果沒有明確為字段賦值醋界,系統(tǒng)自動賦予默認值
案例:
創(chuàng)建數(shù)據(jù)表 tb_test5 并查看表結(jié)構(gòu),其中提完,sex 字段含有三個值,分別對應(yīng)男丘侠、女徒欣、保密三種性別,且默認值為 3 蜗字。
插入一條只給 username 賦值的記錄時 打肝,查詢記錄脂新,可以發(fā)現(xiàn),字段 sex 的記錄值為 3 粗梭,也就是默認值争便。
4、外鍵約束(FOREIGN KEY)
特點:
⑴ 保持數(shù)據(jù)一致性断医,完整性?
⑵ 實現(xiàn)一對一或一對多關(guān)系
要求:
⑴ 父表(字表所參照的表)和子表(具有外鍵列的表)必須使用相同的存儲引擎滞乙,而且禁止使用臨時表。
⑵ 數(shù)據(jù)表的數(shù)據(jù)引擎只能為 InnoDB鉴嗤。
⑶ 外鍵列和參照列必須具有相同的數(shù)據(jù)類型斩启。其中數(shù)字的長度或是否有符號位必須相同;
而字符的長度則可以不同醉锅。
⑷ 外鍵列和參照列必須創(chuàng)建索引兔簇。如果不存在索引的話,MySQL將自動創(chuàng)建索引硬耍。
我們通過以上要求要創(chuàng)建表并賦予外鍵約束垄琐。
案例:
首先查看數(shù)據(jù)庫的默認存儲引擎:
由返回結(jié)果看出,MySQL默認存儲引擎為 InnoDB 经柴。
現(xiàn)在我們創(chuàng)建兩張表狸窘,并對指定的字段賦予相同的數(shù)據(jù)類型:
創(chuàng)建一張省份表并查看該表的引擎:
由圖可以看出,存儲引擎是 InnoDB 滿足要求口锭。
再創(chuàng)建一張用戶表朦前,含有用戶id,用戶名username 鹃操,和用戶所在省份的外鍵 pid 韭寸,此時創(chuàng)建失敗,因為外鍵 pid 的數(shù)據(jù)類型和父表中的 id 數(shù)據(jù)類型不一致導(dǎo)致無法創(chuàng)建荆隘,同樣恩伺,如果外鍵 pid 是否有符號與父表的主鍵 id 不一致,也是無法創(chuàng)建成功的椰拒。
其中晶渠,約束外鍵的語法結(jié)構(gòu)為:
FOREIGN KEY (外鍵 id)REFERENCES 父表名稱 (父表所參照的 id)。
由圖可以得出燃观,外鍵 pid 滿足數(shù)據(jù)類型和是否有符號和父表主鍵 id 一致褒脯,所以該表創(chuàng)建成功。注:外鍵列(pid)和參照列(id)必須創(chuàng)建索引缆毁。
我們來看看兩張表是否有創(chuàng)建索引:
由圖可以看出番川,數(shù)據(jù)表 tb_province 的參照列 id 已經(jīng)創(chuàng)建了主鍵索引。
而對于數(shù)據(jù)表 tb_users ,可以發(fā)現(xiàn)存在兩個索引,一個是主鍵索引 id颁督,另一個 pid 系統(tǒng)已經(jīng)自動創(chuàng)建了索引践啄。
通過查看所該表的創(chuàng)建命令,可以看出系統(tǒng)給 pid 自動創(chuàng)建了索引( KEY 'pid')沉御,同時在
CONSTRAINT 'tb_users_ibfk_1' FOREIGN KEY ('pid')? 可以得出 pid 為外鍵約束屿讽。
在我們創(chuàng)建外鍵約束的時候,可以添加一些外鍵約束的參照操作吠裆,有如下幾種:
⑴ CASCADE:父表刪除或更新行時伐谈,同時自動更新或更新子表匹配的行
⑵ SET NULL:從父表刪除或更新行,并設(shè)置子表中的外鍵列為 NULL 硫痰。如果使用該選項衩婚,必須保證子表列沒有指定 NOT NULL
⑶ RESTRICT:拒絕對父表的刪除或更新操作
⑷ NO ACTION:標(biāo)準(zhǔn) MySQL 的關(guān)鍵字,在 MySQL 中與 RESTRICT 相同
在更新表的時候效斑,可以通過以上選項來設(shè)置子表是否進行相應(yīng)的操作非春。
案例:
我們創(chuàng)建一張 tb_users1 數(shù)據(jù)表,給 pid 設(shè)置為外鍵約束缓屠,同時在刪除的時候奇昙,設(shè)置 CASCADE 選項。
接下來通過插入信息來驗證一下敌完。由于子表(tb_users1)參照父表(tb_province)储耐,為了保證子表有參照數(shù)據(jù),必須先在父表里插入記錄滨溉。
對父表(tb_province)依次插入三條記錄什湘,并查詢所有記錄。
對子表(tb_user1)依次插入三條記錄晦攒,并查詢所有數(shù)據(jù)闽撤。
現(xiàn)在兩張表都存在記錄,我們先通過刪除記錄來驗證一下脯颜,CASCADE 選項哟旗。
首先刪除父表(tb_province)中 id 為 2 的記錄:
查詢 tb_province 所有記錄:
可以看出,原先記錄 id = 2 已經(jīng)被刪除了栋操。
我們再來查詢一下子表中 pid = 3 的記錄是否還存在:
由圖可以得知闸餐,pid = 2 的所有記錄已經(jīng)被刪除了。
這就是 CASCADE 所起的作用矾芙,父表刪除記錄同時刪除子表所相關(guān)的記錄舍沙,同理更新的操作也會影響子表的記錄。
在實際開發(fā)中剔宪,我們很少使用物理的外鍵約束拂铡,一般使用邏輯的外鍵約束戈锻,因為物理外鍵約束只有在 InnoDB 引擎下才得以支持,而物理外鍵可以通過在兩張表中存在某種結(jié)構(gòu)來定義約束和媳,而不使用 FORENGIEN KEY 這個關(guān)鍵詞來定義。
總結(jié):
列級約束使用比較多哈街,表級約束很少使用留瞳,在以上幾種約束中,NOT NULL 約束骚秦,DEFAULT 約束這兩種約束不存在表級約束她倘,它們只有列級約束,而對于其他的三種作箍,PRIMARY KEY 約束硬梁,UNIQUE 約束,F(xiàn)ORENGIEN KEY 約束胞得,它們都可以存在表級和列級約束荧止。
約束分為以下幾種:
⑴ 功能
? ??① NOT NULL (非空約束)
????② PRIMARY KEY(主鍵約束)
????③ UNIQUE KEY(唯一約束)
????④ DEFAULT(默認約束)
????⑤ FROEIGN KEY(外鍵約束)
⑵ 數(shù)據(jù)列的數(shù)目
? ??① 表級約束
????② 列級約束
以上為本人的一些學(xué)習(xí)筆記,如有出錯歡迎指正阶剑,陸續(xù)更新T狙病!牧愁!