MySQL約束

概念:

為了保證數(shù)據(jù)的完整性和一致性,MySQL提供了約束這個(gè)屬性。約束分為表級(jí)約束和列級(jí)約束,如果約束只是針對(duì)某一個(gè)字段來(lái)說(shuō),則稱之為列級(jí)約束,如果針對(duì)兩個(gè)或者兩個(gè)以上的,則稱之為表級(jí)約束。列級(jí)約束既可以在列定義時(shí)聲明,也可以在列定義后聲明,而表級(jí)約束只能在列定義后聲明。

約束類型包括以下幾種:

NOT NULL (非空約束)

PRIMARY KEY (主鍵約束)

UNIQUE KEY (唯一約束)

DEFAULT (默認(rèn)約束)

FOREIGN KEY (外鍵約束)

場(chǎng)景:

在操作數(shù)據(jù)表時(shí),為了避免插入重復(fù)的數(shù)據(jù),可以在字段后面添加 AUTO_INCREMENT(自動(dòng)編號(hào)) 屬性來(lái)保證記錄的唯一性,并且該字段必須為整型或者字符型,若使用字符型,小數(shù)必須為 0 。

該屬性如下特點(diǎn):

⑴ 賦予自動(dòng)編號(hào)屬性的字段必須定義為主鍵

⑵ 在默認(rèn)情況下,起始值為1,每次遞增加1

案例:

創(chuàng)建一張 tb_test2 數(shù)據(jù)表,并且給 id 字段賦予 AUTO_INCREMENT 屬性,系統(tǒng)報(bào)錯(cuò),根據(jù)信息可以看出,字段 id 必須設(shè)置為主鍵。接下來(lái)我們來(lái)了解一下主鍵約束和其他約束。(非空約束在上一文結(jié)尾已提及)

1、主鍵約束 (PRIMARY KEY)

特點(diǎn):

⑴ 每張數(shù)據(jù)表只能存在一個(gè)主鍵

⑵ 主鍵可以保證記錄的唯一性

⑶ 主鍵自動(dòng)默認(rèn)為 NOT NULL

案例:

以剛才創(chuàng)建的表為例,重新創(chuàng)建數(shù)據(jù)表,在 id 后添加 PRIMARY KEY 屬性表示該字段為主鍵。

接著查看數(shù)據(jù)表的結(jié)構(gòu):

可以發(fā)現(xiàn),字段 id 不為 NULL 符合 AUTO_INCREMENT 屬性特點(diǎn),key 的值為 PRI,說(shuō)明該字段為主鍵,而 username 在創(chuàng)建時(shí)已經(jīng)指定為 NOT NULL 。當(dāng)我們依次插入數(shù)據(jù)時(shí),對(duì)應(yīng)的id 會(huì)自動(dòng)增長(zhǎng)。

案例:(數(shù)據(jù)表的記錄操作會(huì)在后續(xù)的文章提及)

依次插入三條記錄,并查看所有記錄,數(shù)據(jù)表的 id 自動(dòng)遞增。

注: AUTO_INCREMENT 必須和 PRIMARY KEY 一起使用,而 PRIMARY KEY 不一定和

AUTO_INCREMENT 一起使用。

案例:

當(dāng)我們創(chuàng)建數(shù)據(jù)表并沒(méi)有給主鍵 id 賦予 AUTO_INCREMENT 時(shí),系統(tǒng)提示創(chuàng)建成功,此時(shí)的 id 不能為空,查詢表結(jié)構(gòu)可以看出 Extra 字段沒(méi)有 auto_increment 屬性。我們插入一些記錄來(lái)驗(yàn)證一下:

在插入記錄時(shí),分別對(duì) id 和 username 字段進(jìn)行賦值,但是不允許插入兩條相同的記錄:

當(dāng)我們插入相同 id 的記錄時(shí),系統(tǒng)報(bào)錯(cuò),提示表已存在該記錄。

在一張數(shù)據(jù)表中,除了主鍵約束外,為了保證記錄的唯一性,MySQL 提供了另一種約束,

就是唯一約束。

2、唯一約束 (UNIQUE KEY)

特點(diǎn):

⑴ 唯一約束可以保證記錄的唯一性

⑵ 唯一約束的字段可以為空值(NULL)

⑶ 每張數(shù)據(jù)表可以存在多個(gè)唯一約束

當(dāng)然了,對(duì)于指定唯一約束的字段來(lái)說(shuō),如果插入的多條記錄都為空,表里也只存在一條空記錄,保證唯一性。

案例:

創(chuàng)建表 tb_test4 ,字段 id 為主鍵且自動(dòng)增長(zhǎng),username 為字符型且唯一約束。

我們插入記錄驗(yàn)證一下:

插入一條記錄提示成功。

重新插入一條相同的記錄,系統(tǒng)報(bào)錯(cuò),不能重復(fù)添加,說(shuō)明 username 被賦予唯一約束,只能插入一條記錄。

3、默認(rèn)約束 (DEFAULT)

特點(diǎn):

當(dāng)插入記錄時(shí),如果沒(méi)有明確為字段賦值,系統(tǒng)自動(dòng)賦予默認(rèn)值

案例:

創(chuàng)建數(shù)據(jù)表 tb_test5 并查看表結(jié)構(gòu),其中,sex 字段含有三個(gè)值,分別對(duì)應(yīng)男、女、保密三種性別,且默認(rèn)值為 3 。

插入一條只給 username 賦值的記錄時(shí) ,查詢記錄,可以發(fā)現(xiàn),字段 sex 的記錄值為 3 ,也就是默認(rèn)值。

4、外鍵約束(FOREIGN KEY)

特點(diǎn):

⑴ 保持?jǐn)?shù)據(jù)一致性,完整性?

⑵ 實(shí)現(xiàn)一對(duì)一或一對(duì)多關(guān)系

要求:

⑴ 父表(字表所參照的表)和子表(具有外鍵列的表)必須使用相同的存儲(chǔ)引擎,而且禁止使用臨時(shí)表。

⑵ 數(shù)據(jù)表的數(shù)據(jù)引擎只能為 InnoDB。

⑶ 外鍵列和參照列必須具有相同的數(shù)據(jù)類型。其中數(shù)字的長(zhǎng)度或是否有符號(hào)位必須相同;

而字符的長(zhǎng)度則可以不同。

⑷ 外鍵列和參照列必須創(chuàng)建索引。如果不存在索引的話,MySQL將自動(dòng)創(chuàng)建索引。

我們通過(guò)以上要求要?jiǎng)?chuàng)建表并賦予外鍵約束。

案例:

首先查看數(shù)據(jù)庫(kù)的默認(rèn)存儲(chǔ)引擎:

由返回結(jié)果看出,MySQL默認(rèn)存儲(chǔ)引擎為 InnoDB 。

現(xiàn)在我們創(chuàng)建兩張表,并對(duì)指定的字段賦予相同的數(shù)據(jù)類型:

創(chuàng)建一張省份表并查看該表的引擎:

由圖可以看出,存儲(chǔ)引擎是 InnoDB 滿足要求。

再創(chuàng)建一張用戶表,含有用戶id,用戶名username ,和用戶所在省份的外鍵 pid ,此時(shí)創(chuàng)建失敗,因?yàn)橥怄I pid 的數(shù)據(jù)類型和父表中的 id 數(shù)據(jù)類型不一致導(dǎo)致無(wú)法創(chuàng)建,同樣,如果外鍵 pid 是否有符號(hào)與父表的主鍵 id 不一致,也是無(wú)法創(chuàng)建成功的。

其中,約束外鍵的語(yǔ)法結(jié)構(gòu)為:

FOREIGN KEY (外鍵 id)REFERENCES 父表名稱 (父表所參照的 id)。

由圖可以得出,外鍵 pid 滿足數(shù)據(jù)類型和是否有符號(hào)和父表主鍵 id 一致,所以該表創(chuàng)建成功。注:外鍵列(pid)和參照列(id)必須創(chuàng)建索引。

我們來(lái)看看兩張表是否有創(chuàng)建索引:

由圖可以看出,數(shù)據(jù)表 tb_province 的參照列 id 已經(jīng)創(chuàng)建了主鍵索引。

而對(duì)于數(shù)據(jù)表 tb_users ,可以發(fā)現(xiàn)存在兩個(gè)索引,一個(gè)是主鍵索引 id,另一個(gè) pid 系統(tǒng)已經(jīng)自動(dòng)創(chuàng)建了索引。

通過(guò)查看所該表的創(chuàng)建命令,可以看出系統(tǒng)給 pid 自動(dòng)創(chuàng)建了索引( KEY 'pid'),同時(shí)在

CONSTRAINT 'tb_users_ibfk_1' FOREIGN KEY ('pid')? 可以得出 pid 為外鍵約束。

在我們創(chuàng)建外鍵約束的時(shí)候,可以添加一些外鍵約束的參照操作,有如下幾種:

⑴ CASCADE:父表刪除或更新行時(shí),同時(shí)自動(dòng)更新或更新子表匹配的行

⑵ SET NULL:從父表刪除或更新行,并設(shè)置子表中的外鍵列為 NULL 。如果使用該選項(xiàng),必須保證子表列沒(méi)有指定 NOT NULL

⑶ RESTRICT:拒絕對(duì)父表的刪除或更新操作

⑷ NO ACTION:標(biāo)準(zhǔn) MySQL 的關(guān)鍵字,在 MySQL 中與 RESTRICT 相同

在更新表的時(shí)候,可以通過(guò)以上選項(xiàng)來(lái)設(shè)置子表是否進(jìn)行相應(yīng)的操作。

案例:

我們創(chuàng)建一張 tb_users1 數(shù)據(jù)表,給 pid 設(shè)置為外鍵約束,同時(shí)在刪除的時(shí)候,設(shè)置 CASCADE 選項(xiàng)。

接下來(lái)通過(guò)插入信息來(lái)驗(yàn)證一下。由于子表(tb_users1)參照父表(tb_province),為了保證子表有參照數(shù)據(jù),必須先在父表里插入記錄。

對(duì)父表(tb_province)依次插入三條記錄,并查詢所有記錄。

對(duì)子表(tb_user1)依次插入三條記錄,并查詢所有數(shù)據(jù)。

現(xiàn)在兩張表都存在記錄,我們先通過(guò)刪除記錄來(lái)驗(yàn)證一下,CASCADE 選項(xiàng)。

首先刪除父表(tb_province)中 id 為 2 的記錄:

查詢 tb_province 所有記錄:

可以看出,原先記錄 id = 2 已經(jīng)被刪除了。

我們?cè)賮?lái)查詢一下子表中 pid = 3 的記錄是否還存在:

由圖可以得知,pid = 2 的所有記錄已經(jīng)被刪除了。

這就是 CASCADE 所起的作用,父表刪除記錄同時(shí)刪除子表所相關(guān)的記錄,同理更新的操作也會(huì)影響子表的記錄。

在實(shí)際開(kāi)發(fā)中,我們很少使用物理的外鍵約束,一般使用邏輯的外鍵約束,因?yàn)槲锢硗怄I約束只有在 InnoDB 引擎下才得以支持,而物理外鍵可以通過(guò)在兩張表中存在某種結(jié)構(gòu)來(lái)定義約束,而不使用 FORENGIEN KEY 這個(gè)關(guān)鍵詞來(lái)定義。

總結(jié):

列級(jí)約束使用比較多,表級(jí)約束很少使用,在以上幾種約束中,NOT NULL 約束,DEFAULT 約束這兩種約束不存在表級(jí)約束,它們只有列級(jí)約束,而對(duì)于其他的三種,PRIMARY KEY 約束,UNIQUE 約束,F(xiàn)ORENGIEN KEY 約束,它們都可以存在表級(jí)和列級(jí)約束。

約束分為以下幾種:

⑴ 功能

? ??① NOT NULL (非空約束)

????② PRIMARY KEY(主鍵約束)

????③ UNIQUE KEY(唯一約束)

????④ DEFAULT(默認(rèn)約束)

????⑤ FROEIGN KEY(外鍵約束)

⑵ 數(shù)據(jù)列的數(shù)目

? ??① 表級(jí)約束

????② 列級(jí)約束

以上為本人的一些學(xué)習(xí)筆記,如有出錯(cuò)歡迎指正,陸續(xù)更新?。?!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 觀其大綱 page 01 基礎(chǔ)知識(shí) 1 MySQL數(shù)據(jù)庫(kù)概要 2 簡(jiǎn)單MySQL環(huán)境 3 數(shù)據(jù)的存儲(chǔ)和獲取 4 M...
    周少言閱讀 3,255評(píng)論 0 33
  • MYSQL 基礎(chǔ)知識(shí) 1 MySQL數(shù)據(jù)庫(kù)概要 2 簡(jiǎn)單MySQL環(huán)境 3 數(shù)據(jù)的存儲(chǔ)和獲取 4 MySQL基本操...
    Kingtester閱讀 8,060評(píng)論 5 115
  • 接下來(lái)的一些內(nèi)容,我們需要提前學(xué)一些簡(jiǎn)單的sql語(yǔ)句,方便大家理解接下來(lái)的知識(shí)。 DDL—數(shù)據(jù)定義語(yǔ)言(Creat...
    不排版閱讀 475評(píng)論 0 1
  • 托爾斯泰寫(xiě)過(guò)一個(gè)小故事。講述了一個(gè)關(guān)于皇帝的三個(gè)問(wèn)題的故事。讀后頗有感觸。 1.做每件事的最佳時(shí)機(jī)是什么時(shí)候...
    028黃小丸閱讀 178評(píng)論 0 0
  • 廣義上講: 輕量級(jí)與重量級(jí)是一個(gè)相對(duì)的概念,主要是對(duì)應(yīng)用框架使用方便性和所提供 服務(wù)特性等方面做比較的。比方說(shuō)EJ...
    背麻袋的袋鼠閱讀 2,673評(píng)論 0 2

友情鏈接更多精彩內(nèi)容