MySQL數(shù)據(jù)庫(kù)之表的約束圖文詳解
一、表的約束
前面我們所講到的數(shù)據(jù)類型就是一種表的約束。為什么這么說(shuō)呢?因?yàn)閿?shù)據(jù)類型有自己的大小,也就是我們插入的數(shù)據(jù)是有范圍的,不能夠隨意插入,這就對(duì)程序員的插入操作作了規(guī)范和約束,保證了插入的數(shù)據(jù)的合法性和完整性以及可預(yù)期性。
但是數(shù)據(jù)類型約束很單一,需要有一些額外的約束,更好的保證數(shù)據(jù)的合法性,從業(yè)務(wù)邏輯角度保證數(shù)據(jù)的正確性。比如:身高不能為負(fù)數(shù),每個(gè)人的電話號(hào)碼都是唯一的等。
約束本質(zhì):通過(guò)技術(shù)手段,倒逼程序員,插入正確的數(shù)據(jù)。
二、空屬性
null(默認(rèn)的)和 not null(不為空)
數(shù)據(jù)庫(kù)默認(rèn)字段基本都是字段為空,但是實(shí)際開(kāi)發(fā)時(shí),盡可能保證字段不為空,因?yàn)閿?shù)據(jù)為空沒(méi)辦法參與運(yùn)算。并且有的數(shù)據(jù)是不能為空的。
比如,在學(xué)校中,一個(gè)學(xué)生一定有其所在的班級(jí),且不能為空,因?yàn)槟硞€(gè)學(xué)生一定是屬于一個(gè)確定的班級(jí)的,并且這個(gè)班級(jí)所在的教室也是確定的且不能為空,不然學(xué)生就不知道在哪里上課了。所以如果我們要?jiǎng)?chuàng)建一個(gè)學(xué)生的信息表的話,這兩個(gè)字段不能夠?yàn)榭铡?nbsp;
我們先創(chuàng)建一個(gè)學(xué)生信息表:
mysql> create table stu( -> name varchar(20), -> class_name varchar(20) not null, -> class_room varchar(20) not null -> );
如下圖的表結(jié)構(gòu):null一欄,yes表示可以為空,no表示不能為空。
然后我們向其中插入一些數(shù)據(jù):
而如果我們插入null數(shù)據(jù)的話,就會(huì)出錯(cuò):
而允許為空的列,它的默認(rèn)值是null。所以如果插入null,則是合法的:
三、默認(rèn)值
默認(rèn)值(default):某一種數(shù)據(jù)會(huì)經(jīng)常性的出現(xiàn)某個(gè)具體的值,可以在一開(kāi)始就指定好,在需要真實(shí)數(shù)據(jù)的時(shí)候,用戶可以選擇性的使用默認(rèn)值。
下面我們?cè)趯W(xué)生信息表中插入一列年齡信息,并設(shè)置其默認(rèn)值是18。
下面我們進(jìn)行包含age數(shù)據(jù)的插入,和不包含age數(shù)據(jù)的插入:
我們發(fā)現(xiàn),如果用戶指明了年齡,就使用用戶指定的年齡,如果用戶沒(méi)有指明年齡,就使用我們?cè)O(shè)置的默認(rèn)值。默認(rèn)值的生效:數(shù)據(jù)在插入的時(shí)候不給該字段賦值,就使用默認(rèn)值。
如果沒(méi)有明確指定一列要插入,用的是default值,而如果沒(méi)有設(shè)置default值,就會(huì)出錯(cuò):比如下面,name就沒(méi)有設(shè)置default值。
注:只有設(shè)置了default的列,才可以在插入值的時(shí)候,對(duì)列進(jìn)行省略。
四、列描述
列描述:comment,沒(méi)有實(shí)際含義,專門用來(lái)描述字段,會(huì)根據(jù)表創(chuàng)建語(yǔ)句保存,用來(lái)給程序員或DBA來(lái)進(jìn)行了解列字段的含義。
具體使用方式如下:
mysql> create table users( -> name varchar(20) comment '用戶名字', -> address varchar(32) comment '用戶地址', -> telephone int comment '用戶電話' -> );
五、zerofill
引列:對(duì)于下表。
mysql> create table t12( -> id int -> );
我們查看一下它的屬性:
我們發(fā)現(xiàn),int類型后面還跟了一個(gè)數(shù)字10。它肯定不是表示int類型的大小,因?yàn)閕nt類型的大小是4字節(jié),那么這個(gè)10代表什么意思呢?
其實(shí)沒(méi)有zerofill這個(gè)約束的話,括號(hào)內(nèi)的數(shù)字是毫無(wú)意義的。所以我們需要將他們結(jié)合起來(lái)理解。
比如,對(duì)于下表:
mysql> create table t12( -> a int(5), -> b int(5) -> );
一般情況下,我們向表中插入數(shù)據(jù)沒(méi)有什么特別的地方:
但是對(duì)列添加了zerofill約束后,顯示的結(jié)果就有所不同了。修改t12表中,b的約束條件:
alter table t12 change b b int(5) zerofill;
然后,我們?cè)俨榭磘12表中的數(shù)據(jù):
其實(shí),int身后括號(hào)里面的數(shù)字就表示數(shù)值顯示的寬度。這里面顯示的寬度是5。加了zerofill約束后,這次可以看到b的值由原來(lái)的2變成00002,這就是zerofill約束的作用,如果寬度小于設(shè)定的寬度(這里設(shè)置的是5),自動(dòng)填充0。
根據(jù)上面的結(jié)果,要注意的是,這只是最后顯示的結(jié)果,在MySQL中實(shí)際存儲(chǔ)的還是1??梢钥闯鰯?shù)據(jù)庫(kù)內(nèi)部存儲(chǔ)的還是1,00001只是設(shè)置了zerofill屬性后的一種格式化輸出而已。
六、主鍵
主鍵:primary key用來(lái)唯一的約束該字段里面的數(shù)據(jù),不能重復(fù),不能為空,一張表中最多只能有一個(gè)主鍵。主鍵所在的列通常是整數(shù)類型。
創(chuàng)建表的時(shí)候直接在字段上指定主鍵約束(primary key)。我們先創(chuàng)建一個(gè)包含主鍵約束的學(xué)生信息表:
mysql> create table stu( -> id int primary key, -> name varchar(20), -> password int -> );
然后查看其列屬性:列屬性中key一列中pri表示該字段是主鍵。
先插入兩條數(shù)據(jù):
如果我們?cè)俨迦胍粭lid為2的記錄,就會(huì)報(bào)錯(cuò):
報(bào)錯(cuò)的提示信息就是id為2的主鍵沖突了。即主鍵對(duì)應(yīng)的字段中不能重復(fù),一旦重復(fù),插入操作就會(huì)失敗。
當(dāng)表創(chuàng)建好以后,但是沒(méi)有在創(chuàng)建時(shí)就指定主鍵的時(shí)候,可以再次追加主鍵。
alter table 表名 add primary key(字段列表);
當(dāng)你不再需要主鍵的時(shí)候, 可以刪除主鍵:
alter table 表名 drop primary key;
復(fù)合主鍵:在創(chuàng)建表的時(shí)候,在所有字段之后,使用primary key來(lái)創(chuàng)建主鍵,如果設(shè)置多個(gè)字段作為主鍵,這就是復(fù)合主鍵。
我們先創(chuàng)建一個(gè)包含復(fù)合主鍵約束的學(xué)生信息表:id表示學(xué)生編號(hào),crouse_id表示課程編號(hào),score表示該學(xué)生該課程的分?jǐn)?shù)。
mysql> create table stu( -> id int, -> crouse_id int, -> score int, -> primary key(id,crouse_id) -> );
然后我們向其中插入一些數(shù)據(jù):
我們發(fā)現(xiàn),對(duì)于復(fù)合主鍵,這里是(id,crouse_id),只要兩個(gè)中有一個(gè)和表中數(shù)據(jù)不一樣,就可以插入成功。如果兩個(gè)中同時(shí)和表中的數(shù)據(jù)沖突了,那么插入失敗。也就是說(shuō),(id,crouse_id)同時(shí)構(gòu)成了主鍵。用上面的例子解釋的話,就是一個(gè)同學(xué)可以選多個(gè)課程,多個(gè)同學(xué)選同一個(gè)課程,但是同一個(gè)同學(xué)不能多次選擇同一個(gè)課程。
七、自增長(zhǎng)
auto_increment:當(dāng)對(duì)應(yīng)的字段不給值,會(huì)自動(dòng)的被系統(tǒng)觸發(fā),系統(tǒng)會(huì)從當(dāng)前字段中已經(jīng)有的最大值 +1操作,得到一個(gè)新的不同的值。通常和主鍵搭配使用,作為邏輯主鍵。
自增長(zhǎng)的特點(diǎn):
~ 任何一個(gè)字段要做自增長(zhǎng),前提是本身是一個(gè)索引(key一欄有值)。
~ 自增長(zhǎng)字段必須是整數(shù)。
~ 一張表最多只能有一個(gè)自增長(zhǎng)。
我們先創(chuàng)建一個(gè)包含自增長(zhǎng)約束的信息表:
mysql> create table stu( -> id int primary key auto_increment, -> name varchar(20) -> );
然后我們插入一些數(shù)據(jù),并進(jìn)行查詢:
我們發(fā)現(xiàn),有了自增長(zhǎng)約束,我們不需要手動(dòng)插入id數(shù)據(jù),并且每次插入它還會(huì)自加1。這樣還保證了主鍵不會(huì)沖突。
如果我手動(dòng)插入id,會(huì)是怎么樣呢?
從上面的結(jié)果可以看出,如果我們手動(dòng)插入, 就會(huì)是我們用戶自己指定的數(shù)據(jù)進(jìn)行插入。而下一次插入時(shí),也不指定id的話,id就會(huì)從13開(kāi)始自增。
當(dāng)然,我們也可以在創(chuàng)建表的時(shí)候就指定自增長(zhǎng)值:
mysql> create table stu1( -> id int primary key auto_increment, -> name varchar(20) -> )auto_increment=10;
插入數(shù)據(jù):
八、唯一鍵
一張表中有往往有很多字段需要唯一性,使其數(shù)據(jù)不能重復(fù)。但是一張表中只能有一個(gè)主鍵,所以唯一鍵就可以解決表中有多個(gè)字段需要唯一性約束的問(wèn)題。
唯一鍵的本質(zhì)和主鍵差不多,唯一鍵允許為空,而且可以多個(gè)為空,空字段不做唯一性比較。
我們創(chuàng)建如下的學(xué)生信息表:
mysql> create table stu( -> id int primary key auto_increment, -> telphone int unique key -> );
如下,key一列中的UNI就表示該字段是唯一鍵:
然后我們向表中插入一些數(shù)據(jù):
我們發(fā)現(xiàn),如果telphone插入相同的值就會(huì)報(bào)錯(cuò),報(bào)錯(cuò)就是唯一鍵發(fā)生了沖突。
唯一鍵是可以為空的:
唯一鍵 VS 主鍵
主鍵:主要是用來(lái)標(biāo)識(shí)表中一條數(shù)據(jù)的唯一性。
唯一鍵:主要是用來(lái)標(biāo)識(shí)某一列的字段的數(shù)據(jù)不能出現(xiàn)重復(fù)。
九、外鍵
外鍵用于定義主表和從表之間的關(guān)系:外鍵約束主要定義在從表上,主表則必須是有主鍵約束或unique約束。當(dāng)定義外鍵后,要求外鍵列數(shù)據(jù)必須在主表的主鍵列存在或?yàn)閚ull。
語(yǔ)法:
foreign key (字段名) references 主表(列)
下面創(chuàng)建一張班級(jí)信息表(主表):
mysql> create table class( -> id int primary key, -> name varchar(20) not null -> );
插入一些數(shù)據(jù):
再創(chuàng)建一張學(xué)生表(從表):
create table stu( id int primary key, name varchar(20) not null, class_id int, foreign key (class_id) references class(id) );
下圖,key列 MUL 就表示該字段是外鍵。
插入數(shù)據(jù):
如果我們?cè)趕tu表中插入class表中不存在的班級(jí)會(huì)發(fā)生什么呢?插入一個(gè)班級(jí)號(hào)為3的學(xué)生,因?yàn)閏lass表中沒(méi)有這個(gè)班級(jí),所以插入失敗了。
我們發(fā)現(xiàn),報(bào)錯(cuò)提示會(huì)告訴我們不存在3號(hào)外鍵。
如下圖,如果我們想要?jiǎng)h除班級(jí)號(hào)為1的班級(jí)信息,就會(huì)報(bào)錯(cuò),因?yàn)榘嗉?jí)號(hào)為1的班級(jí)里還有學(xué)生。
總結(jié)
到此這篇關(guān)于MySQL數(shù)據(jù)庫(kù)之表的約束的文章就介紹到這了,更多相關(guān)MySQL表的約束內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Winserver2012下mysql 5.7解壓版(zip)配置安裝教程詳解
這篇文章主要介紹了Winserver2012下mysql 5.7解壓版(zip)配置安裝教程詳解,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01mysql 控制臺(tái)程序的提示符 prompt 字符串設(shè)置
mysql 控制臺(tái)程序的提示符 prompt 字符串設(shè)置,學(xué)習(xí)mysql的朋友可以參考下。2011-08-08windows下mysql 8.0.16 安裝配置方法圖文教程
這篇文章主要為大家詳細(xì)介紹了windows下mysql 8.0.16 安裝配置方法圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05linux環(huán)境下配置mysql5.6支持IPV6連接的方法
本文主要介紹在linux系統(tǒng)下,如何配置mysql支持IPV6的連接,本文圖文并茂給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友參考下吧2018-01-01mysql 8.0.22壓縮包完整安裝與配置教程圖解(親測(cè)安裝有效)
這篇文章主要介紹了mysql 8.0.22壓縮包完整安裝與配置教程圖解(親測(cè)安裝有效),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12關(guān)于MYSQL 你需要知道的數(shù)據(jù)類型和操作數(shù)據(jù)表
這篇文章主要介紹了關(guān)于MYSQL中數(shù)據(jù)類型的知識(shí)和操作數(shù)據(jù)表的方法,文中講解非常詳細(xì)供大家參考學(xué)習(xí),感興趣的朋友可以了解下2020-06-06Kubernetes中實(shí)現(xiàn) MySQL 讀寫分離的詳細(xì)步驟
Kubernetes中實(shí)現(xiàn)MySQL的讀寫分離通過(guò)主從復(fù)制架構(gòu),利用Kubernetes部署MySQL主節(jié)點(diǎn)和從節(jié)點(diǎn),并通過(guò)Service實(shí)現(xiàn)讀寫分離,提高數(shù)據(jù)庫(kù)性能和可維護(hù)性2024-11-11