MySQL中關(guān)于表的約束
一、空屬性
在MySQL中,空屬性約束指定了某一列是否可以包含NULL值。
它們用于各種目的,例如數(shù)據(jù)驗(yàn)證和限制數(shù)據(jù)的輸入格式。
NOT NULL
:當(dāng)使用NOT NULL屬性約束時(shí),將禁止該列包含NULL值。這意味著在插入或者更新數(shù)據(jù)時(shí),該列必須包含有效的數(shù)值或字符,不能為NULL。NULL
:如果沒(méi)有顯式地指定NULL或NOT NULL屬性約束,那么默認(rèn)情況下,列可以包含NULL值。這意味著在插入或更新數(shù)據(jù)時(shí),如果沒(méi)有提供有效的值,可以將該列的值設(shè)置為NULL。
如上圖所示,我們把id 和 name 均設(shè)置了 not null(不為空)。
其中并沒(méi)有對(duì)high設(shè)置,默認(rèn)就是可以為空的。
我們?cè)俨迦霐?shù)據(jù)進(jìn)行查看,如下:
從上圖中可以看到,當(dāng)對(duì)字段設(shè)置了不能為空時(shí),插入的時(shí)候就不能再插入NULL值。當(dāng)可以為空時(shí),插入NULL值和其對(duì)應(yīng)的類型的值均為可以的。
在實(shí)際應(yīng)用開(kāi)發(fā)中,比如我們?cè)诓迦霐?shù)據(jù)并不能準(zhǔn)確的知道數(shù)據(jù)的值,就可以暫時(shí)插入NULL值。當(dāng)設(shè)置了不能為空時(shí),這就約束著必須插入有效的值。
通過(guò)合理地應(yīng)用空屬性約束,可以有效地避免數(shù)據(jù)中的空值或缺失值,從而提高數(shù)據(jù)質(zhì)量和可靠性。
二、默認(rèn)值
在MySQL中,默認(rèn)值約束用于定義表列的默認(rèn)值。當(dāng)插入新記錄時(shí),如果沒(méi)有為該列提供值,則可以使用默認(rèn)值來(lái)填充該列。這有助于減少數(shù)據(jù)冗余并提高數(shù)據(jù)庫(kù)的一致性。
當(dāng)某一種數(shù)據(jù)會(huì)經(jīng)常性的出現(xiàn)某個(gè)具體的值,可以在一開(kāi)始就指定好,在需要真實(shí)數(shù)據(jù)的時(shí)候,用戶可以選擇性的使用默認(rèn)值。
下面我們看一個(gè)具體的實(shí)例:
在上圖中我們將性別默認(rèn)設(shè)置成 ‘女’。
當(dāng)插入數(shù)據(jù)時(shí)不提插入性別時(shí),默認(rèn)就是 ‘女’。
具體如下圖:
通過(guò)上圖看到,當(dāng)我們不再插入性別時(shí)默認(rèn)給我們填充了‘女’,當(dāng)然也可以自己指定。
我們也可查看表結(jié)構(gòu),看其詳細(xì)的默認(rèn)值,如下圖:
當(dāng)我們不指定其默認(rèn)值時(shí),默認(rèn)給我們指定了默認(rèn)值為NULL。
我們?cè)倏慈缦碌牟迦耄?/p>
假如設(shè)置一個(gè)字段不為空時(shí),默認(rèn)值還會(huì)自動(dòng)設(shè)置為NULL嗎?
我們不妨通過(guò)下圖看一下:
那么 default約束 和 空屬性約束 是不是沖突的呢?
當(dāng)我們?cè)O(shè)置了default時(shí),這就意味著即使我們不插入數(shù)據(jù)也不為空,因?yàn)闀?huì)默認(rèn)使用默認(rèn)值填充。
default約束和not null約束同時(shí)出現(xiàn)并沒(méi)有太大的意義。因?yàn)橐坏O(shè)置的default約束,就可以保證了 not null 約束。
但是我們要區(qū)分的是:
default
是我們不顯示的向指定列插入,default會(huì)自動(dòng)插入。NULL
是顯示的向一列插入。如果插入正常值,就正常工作。如果不確定就插入NULL。但是有not null約束時(shí),就必須插入有效值。
其實(shí)他們之前也并不沖突,反而是相輔相成的。當(dāng)我們不指定插入時(shí),可以用到default約束。指定插入就可以選擇空約束。
三、列描述
所謂列描述,就是我們之前一直在使用的對(duì)列的注釋信息。用到的關(guān)鍵詞是comment,沒(méi)有實(shí)際含義,專門用來(lái)描述字段,會(huì)根據(jù)表創(chuàng)建語(yǔ)句保存,用來(lái)給程序員或DBA來(lái)進(jìn)行了解。
desc查看表結(jié)構(gòu)時(shí)并不能看到注釋信息,如下:
可以通過(guò)show來(lái)查看建表時(shí)的注釋信息,如下圖:
四、zerofill
在MySQL中,zerofill約束是一種用于數(shù)值字段的約束,它會(huì)在數(shù)值字段的值前面添加零,使其達(dá)到指定的長(zhǎng)度。這通常用于保持?jǐn)?shù)值字段的位數(shù)一致性,尤其對(duì)于需要顯示位數(shù)對(duì)齊的情況非常有用。
當(dāng)你在MySQL中創(chuàng)建一個(gè)數(shù)值字段,并為其添加zerofill約束時(shí),MySQL會(huì)自動(dòng)在存儲(chǔ)數(shù)據(jù)時(shí)將數(shù)值填充為指定長(zhǎng)度,并在需要的情況下,自動(dòng)在數(shù)值前面添加零。
我們一直沒(méi)有解釋int(11)中的11的含義是什么,如下圖:
其實(shí)就是代表的整型的位數(shù),表示的是11位。
int的取值范圍是大約是21億正負(fù),最多也就是十位數(shù)字,負(fù)數(shù)的話再加上符號(hào)相當(dāng)于11位了。那么無(wú)符號(hào)整數(shù)是不是10位就可以了呢?是的。
如下圖所示:
我們也可以通過(guò)zerofill約束來(lái)驗(yàn)證一下。
我們現(xiàn)在將 id 的字段屬性修改一下,增加上zerofill約束。
如下圖:
我們?cè)賮?lái)插入一條數(shù)據(jù),觀察是否會(huì)自動(dòng)補(bǔ)0:
如上圖所示,正是我們所說(shuō)的那樣,不夠位數(shù)時(shí)會(huì)自動(dòng)在前面補(bǔ)0。因?yàn)闀r(shí)無(wú)符號(hào)的整數(shù),所以一共是10位。
五、主鍵
在MySQL中,主鍵約束用于唯一標(biāo)識(shí)表中的每一行數(shù)據(jù)。怎么理解這句話呢?
通俗來(lái)講,一個(gè)事物可能會(huì)有很多的字段屬性,其中某一個(gè)屬性或者多個(gè)屬性組合能夠唯一標(biāo)示該事物,我們可以將該字段設(shè)置成主鍵類型。
舉個(gè)例子,一個(gè)合法的中國(guó)公民,都會(huì)有自己的身份證,每個(gè)人的身份證號(hào)是不同的,且身份證號(hào)能夠唯一的標(biāo)示某個(gè)人,那么身份證號(hào)就可以設(shè)置成主鍵類型。下面我們通過(guò)一個(gè)實(shí)際例子來(lái)看:
上圖的例子中,我們?cè)O(shè)置學(xué)生的學(xué)號(hào)為主鍵(primary key),用來(lái)唯一標(biāo)示一個(gè)學(xué)生的信息。
注意:主鍵對(duì)應(yīng)的字段的值不能重復(fù),不能為空,一張表中最多只能有一個(gè)主鍵,且主鍵所在的列通常是整數(shù)類型。
下面我們來(lái)插入一些數(shù)據(jù)來(lái)驗(yàn)證一下:
上圖驗(yàn)證的主鍵對(duì)應(yīng)的字段的值不能重復(fù)。一但重復(fù),就會(huì)報(bào)錯(cuò)不讓你進(jìn)行操作。
再看如下圖,主鍵對(duì)應(yīng)的字段的值也不能為NULL:
當(dāng)我們不想要這個(gè)主鍵時(shí),直接將其刪除掉即可。
如下圖:
我們也不用指定刪除那個(gè)字段的主鍵,因?yàn)橐粡埍碇兄辉试S有一個(gè)主鍵。
當(dāng)表創(chuàng)建好以后但是沒(méi)有主鍵的時(shí)候,可以再次追加主鍵。
如下圖:
有時(shí)候一個(gè)字段并不能很好的標(biāo)示數(shù)據(jù)的唯一性,但是多個(gè)字段就可以。
我們也稱之為復(fù)合主鍵。復(fù)合主鍵就是在創(chuàng)建表的時(shí)候,在所有字段之后,使用多個(gè)字段作為主鍵。
具體實(shí)例如下:
如上圖,我們將 id 和 course 同時(shí)構(gòu)成主鍵,他們即為復(fù)合主鍵。
我們?cè)诓榭幢斫Y(jié)構(gòu)時(shí),可以看到 id 和 course 的Key列都有PRI標(biāo)志,并不是說(shuō)明有兩個(gè)主鍵,而是他們兩個(gè)組成了復(fù)合主鍵。并且它們都是不允許為空的。
我們來(lái)插入一些數(shù)據(jù)來(lái)觀察一下:
通過(guò)上圖也不難發(fā)現(xiàn),只有當(dāng)與復(fù)合主鍵中所有的字段的值相同時(shí),才算沖突,并且不會(huì)讓你進(jìn)行插入。復(fù)合主鍵也是主鍵,所以對(duì)主鍵的操作也可以用到復(fù)合主鍵上。
六、自增長(zhǎng)
在MySQL中,自增長(zhǎng)約束是一種非常常見(jiàn)的約束,用于在插入數(shù)據(jù)時(shí)自動(dòng)為表中的主鍵字段生成唯一的遞增值。
這種約束通常用于確保表中的每一行都具有唯一標(biāo)識(shí),并且可以方便地避免手動(dòng)指定主鍵值的繁瑣操作。
自增長(zhǎng)約束通常與主鍵字段一起使用,通過(guò)自動(dòng)分配唯一的、遞增的整數(shù)值來(lái)確保每行數(shù)據(jù)都有一個(gè)獨(dú)特的標(biāo)識(shí)符。
下面我們來(lái)看一個(gè)實(shí)際的例子:
我們下面再來(lái)插入一些值來(lái)觀察一下:
我們?cè)俨迦霑r(shí)并沒(méi)有設(shè)置id的值,但是在創(chuàng)建表的時(shí)候添加了自增長(zhǎng)的約束。
所以我們看到默認(rèn)值是從1開(kāi)始,然后加1增長(zhǎng)。
那要是我們自動(dòng)為id添加了一個(gè)值,那么以后是怎么進(jìn)行增長(zhǎng)的呢?
具體如下:
實(shí)際上數(shù)據(jù)庫(kù)一直在為我們維護(hù)者下一個(gè)的自增長(zhǎng)的值是多少。所以我們用戶可以不再去擔(dān)心這個(gè)問(wèn)題。
重點(diǎn)是自增長(zhǎng)約束通常用于創(chuàng)建主鍵列,以確保數(shù)據(jù)的唯一性和完整性。
它適用于需要唯一標(biāo)識(shí)每個(gè)記錄的場(chǎng)景,例如用戶ID、訂單ID等。
七、唯一鍵
一張表中有往往有很多字段需要唯一性,數(shù)據(jù)不能重復(fù),但是一張表中只能有一個(gè)主鍵。唯一鍵就可以解決表中有多 個(gè)字段需要唯一性約束的問(wèn)題。
MySQL中的唯一鍵約束是用于確保表中某一列(或多列的組合)的數(shù)值在整個(gè)列中是唯一的。
唯一鍵約束通過(guò)在表中創(chuàng)建唯一索引來(lái)實(shí)現(xiàn),其主要作用是防止用戶插入重復(fù)的數(shù)據(jù),確保數(shù)據(jù)的一致性和完整性。
我們知道每個(gè)人的電話號(hào)碼是不能重復(fù)的,所以將telephone字段設(shè)置了unique約束。
我們?cè)賮?lái)插入一些數(shù)據(jù)觀察一下:
通過(guò)上圖,我們也能發(fā)現(xiàn)某個(gè)字段具有唯一性約束時(shí),該字段也可以為NULL。但是主鍵的值是不能為NULL的。其次,一但插入重復(fù)的值,就會(huì)報(bào)錯(cuò)。同時(shí),一張表中可以設(shè)置對(duì)個(gè)唯一鍵,但是一張表中只能有一個(gè)主鍵。
唯一鍵的本質(zhì)和主鍵差不多,唯一鍵允許為空,而且可以多個(gè)為空,空字段不做唯一性比較。關(guān)于唯一鍵和主鍵的區(qū)別: 我們可以簡(jiǎn)單理解成,主鍵更多的是標(biāo)識(shí)唯一性的。而唯一鍵更多的是保證在業(yè)務(wù)上,不要和別的信息出現(xiàn)重復(fù)。
需要注意的是,不是主鍵具有唯一性,而是某個(gè)具有唯一性的字段被選擇成為了主鍵,而那些不是主鍵但是同樣需要唯一性約束的字段就應(yīng)該設(shè)置成唯一鍵。
八、外鍵
外鍵用于定義主表和從表之間的關(guān)系:外鍵約束主要定義在從表上,主表則必須是有主鍵約束或unique約束。當(dāng)定義外鍵后,要求外鍵列數(shù)據(jù)必須在主表的主鍵列存在或?yàn)閚ull。
一個(gè)學(xué)生一定隸屬于一個(gè)班級(jí)。一個(gè)班級(jí)會(huì)有很多學(xué)生。所以當(dāng)我們?cè)诙x學(xué)生表時(shí),班級(jí)的信息一定會(huì)有大量的重復(fù)。
如下圖:
從上圖可知,會(huì)有很多學(xué)生都會(huì)記錄上相同的class_id 與 class_name。
這時(shí)候我們可以單獨(dú)創(chuàng)建一個(gè)班級(jí)表,讓班級(jí)表與學(xué)生表產(chǎn)生一定的聯(lián)系即可。
如下圖:
但是我們需要在student表中保留一個(gè)class的屬性,這樣才能與myclass表建立聯(lián)系。
具體如下圖:
在上圖中,我們把student表中的class_id設(shè)置成了外鍵。class_id在myclass表中是主鍵。那么這個(gè)時(shí)候主表就是myclass表,從表是student表。
主表會(huì)對(duì)從表產(chǎn)生一些約束的,也就是對(duì)帶有外鍵約束的列進(jìn)行約束。
主表中的數(shù)據(jù)如下圖:
下面我們來(lái)對(duì)從表插入一些數(shù)據(jù)看一下:
上圖中從表中的class_id是具有外鍵約束的。這時(shí)向student表中插入數(shù)據(jù)時(shí),如果插入的數(shù)據(jù)對(duì)應(yīng)的class_id是myclass表中存在的,或者插入的class_id為null,那么此時(shí)是允許進(jìn)行插入的。
當(dāng)插入的class_id不是myclass表中存在的,那么就會(huì)插入失敗。通俗理解:當(dāng)試圖插入或更新數(shù)據(jù)時(shí),MySQL會(huì)檢查引用的主鍵列是否存在有效值。如果沒(méi)有有效的主鍵值,則無(wú)法插入或更新數(shù)據(jù)。
所以在對(duì)外表進(jìn)行插入數(shù)據(jù)時(shí),所具有外鍵約束的字段,插入的數(shù)據(jù)必須在主表中存在。否則就會(huì)插入失敗。我們還需要注意的是:外鍵列的值必須是唯一的,不能有重復(fù)值。
九、練習(xí)
有一個(gè)商店的數(shù)據(jù),記錄客戶及購(gòu)物情況,有以下三個(gè)表組成:
商品goods(商品編號(hào)goods_id,商品名goods_name, 單價(jià)unitprice, 商品類別category, 供應(yīng)商provider);客戶customer(客戶號(hào)customer_id,姓名name,住址address,郵箱email,性別sex,身份證card_id);購(gòu)買purchase(購(gòu)買訂單號(hào)order_id,客戶號(hào)customer_id,商品號(hào)goods_id,購(gòu)買數(shù)量nums)。
要求:
每個(gè)表的主外鍵;客戶的姓名不能為空值;郵箱不能重復(fù)。
- goods表如下圖:
- customer表如下圖:
- purchase表如下圖:
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mysql如何創(chuàng)建和刪除唯一索引(unique key)
這篇文章主要介紹了mysql如何創(chuàng)建和刪除唯一索引(unique key)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12解決MySQL8.0報(bào)錯(cuò)Client does not support auth
本文主要介紹了解決MySQL8.0報(bào)錯(cuò)Client does not support authentication protocol requested by server...問(wèn)題,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05MYSQL使用.frm恢復(fù)數(shù)據(jù)表結(jié)構(gòu)的實(shí)現(xiàn)方法
在這里我們探討使用.frm文件恢復(fù)數(shù)據(jù)表機(jī)構(gòu)(當(dāng)然如果你以前備份過(guò)數(shù)據(jù)表,你可以使用調(diào)用備份的數(shù)據(jù)表)2010-02-02MySQL安裝詳解圖文版(V5.5 For Windows)
這幾年一直在用MySQL,并且是Windows+.Net+MySQL的搭配,用MyISAM引擎支持過(guò)單表每天千萬(wàn)以上的數(shù)據(jù)遞增,TB級(jí)的數(shù)據(jù)MySQL游刃有余。2011-09-09win10下mysql 8.0.12 安裝及環(huán)境變量配置教程
這篇文章主要為大家詳細(xì)介紹了MySQL8.0的安裝、配置、啟動(dòng)服務(wù)和登錄及配置環(huán)境變量,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03