mysql约束_不是吧,阿Sir,MySQL约束你竟然还不懂!
以前寫的太亂了,翻出來重新整理下
系列目錄:
MySQL入門,問題不大【增刪改查極速上手】
(一) 引入約束
(1) 約束出現(xiàn)在哪里?
想要講解約束,就要知道約束用在哪里,用來干嘛?
SQL 語言通過定義一個關(guān)系所對應(yīng)的基本表來完成關(guān)系模式的定義,其語句格式為:
CREATE?TABLE?表名(????1>?1>?[],
????[2>?2>?[],...],
????[]
);
符號規(guī)定:下面展示一些定義的時候,為簡便理解,使用中文配合符號表述(會有具體舉例,不用擔(dān)心理解不了)
>< 中的內(nèi)容為實際的語義
[] 中的內(nèi)容為任選項(不填寫也可)
{} 中的內(nèi)容必須顯式的指定
| 為選項符
[,…n] 表示前面的項可以重復(fù)多次
(2) 約束用來干嘛?
約束,就是針對屬性值的一些約束條件,只針對某一列,叫做列級約束、針對多列屬性的約束,叫做表級約束
怎么理解呢?就例如某一列叫做 學(xué)號,我們就指定約束,這一行不允許為 NULL ,同時我們還能指定它為主鍵,這樣通過學(xué)號就可以查找到一條唯一的學(xué)生記錄了,還有例如外鍵知識等等…
總結(jié)起來就一句話:約束用來對表中的數(shù)據(jù)進行限定,保證數(shù)據(jù)的正確性、有效性和完整性
同樣,有了約束知識的鋪墊,我們就可以引申出后面的一些知識,例如多表操作等等,所以約束雖然簡單,還是非常重要的哈~
(二) 常見約束
(1) 主鍵約束
A:基本概念
在關(guān)系模型中,主鍵的本質(zhì)其實就是一個候選鍵
理解非常簡單,就是能通過這個主鍵,確定一個唯一的記錄:例如學(xué)號是學(xué)生實體的候選鍵,一個學(xué)號就能確定這個學(xué)生到底哪個學(xué)生,而我們不選擇姓名,這是因為,姓名在實際的情況中,不能作為一個唯一的標(biāo)識,確認(rèn)一個唯一的學(xué)生記錄
候選鍵:關(guān)系中能唯一標(biāo)志一個元組的最小屬性集
B:特點
確定為主鍵的列,不能為空,也不能重復(fù)!!!
C:具體操作
指定主鍵約束,使用的是 PRIMARY KEY 關(guān)鍵字
一般來說,主鍵約束主要用在創(chuàng)建表時,指定約束的方式有兩種:
① 定義在列后
??sid?INT(8)?PRIMARY?KEY,
??sname?VARCHAR(5),
??department?VARCHAR(32),
??birthday?date
)
② 獨立定義
??sid?INT(8),
??sname?VARCHAR(5),
??department?VARCHAR(32),
??birthday?date,
??PRIMARY?KEY?(sid)?
)
如果在表已經(jīng)創(chuàng)建好的前提下,還可以通過下列兩種方式進行主鍵的指定和刪除
① 刪除主鍵
② 指定主鍵
ALTER?TABLE?students?MODIFY?sid?INT?PRIMARY?KEY;
D:主鍵自增
提到主鍵,就必須提到主鍵自增了,這個功能也是非常常用的,當(dāng)設(shè)置主動自增后,例如你使用高級語言,操作數(shù)據(jù)庫,向?qū)W生表插入一條記錄后,即使不給出主鍵值,主鍵值也會自動生成出來,并且會在最大主鍵值的基礎(chǔ)上 + 1,例如 0,1,2 … ,n
最重要的一點,主鍵必須是整型,才能實現(xiàn)自增喔~
如果主鍵例如 sid 為 varchar 類型,就會有這樣的報錯:Incorrect column specifier for column 'sid'
同樣,主鍵自增一般用在創(chuàng)建表的時候,使用 AUTO_INCREMENT,直接跟在列名后即可
CREATE?TABLE?students??(??sid?INT(8)?PRIMARY?KEY?AUTO_INCREMENT,
??sname?VARCHAR(5),
??department?VARCHAR(32),
??birthday?date
)
如果表已經(jīng)創(chuàng)建好了,還可以進行是否自增的修改
① 設(shè)置主鍵自增
ALTER?TABLE?students?MODIFY?sid?INT?AUTO_INCREMENT;
② 刪除主鍵自增
ALTER?TABLE?students?MODIFY?sid?INT;
說明:上面設(shè)置以及刪除都給出了 CHANGE 和 MODIFY 兩種,有什么區(qū)別呢?
其實細(xì)心的朋友也可以看出來, CHANGE 后要多一個列名 sid(可以修改) ,所以總結(jié)如下:
只修改類型用 MODIFY
既修改列名,也修改類型用 CHANGE
(2) 非空約束
非空約束很好理解,就是指定非空約束列的值不能為空,我們使用 NOT NULL 來實現(xiàn)這個功能
CREATE?TABLE?students??(??sid?INT(8)?PRIMARY?KEY?AUTO_INCREMENT,
??sname?varchar(5)?NOT?NULL,?--?sname?不為空
??department?varchar(32),
??birthday?date
);
很簡單吧,我們已經(jīng)將 sname 這個字段(列)在創(chuàng)建時添加了非空約束,如果 sname 在插入時為NULL ,則會報錯 Column 'sname' cannot be null
如果表已經(jīng)創(chuàng)建好了怎么辦呢?
創(chuàng)建表完后,添加非空約束
刪除 sname 的非空約束
(3) 唯一約束
唯一約束,就是指定這個字段(列)的值必須是唯一的,這種感覺就類似主鍵,例如我們下面要求創(chuàng)建表的時候,指定 sname 不能重名
CREATE?TABLE?students??(??sid?INT(8)?PRIMARY?KEY?AUTO_INCREMENT,
??sname?VARCHAR(5)?NOT?NULL?UNIQUE,?--?sname唯一
??department?VARCHAR(32),
??birthday?date
);
如果添加兩條重名的記錄,就會報錯
INSERT?INTO?students?VALUES?(NULL,'張三','計算機系','2020-06-16');INSERT?INTO?students?VALUES?(NULL,'張三','工商管理系','2019-06-16');
錯誤信息:Duplicate entry '張三' for key 'sname'
同樣,如果已經(jīng)創(chuàng)建表后,又該怎么設(shè)置或者刪除唯一約束呢?
在創(chuàng)建表后,添加唯一約束
刪除唯一約束(本質(zhì)上就是刪除索引)
--?這兩種方法都是可以的
drop?index?sname?on?students;
(4) 外鍵約束
A:概念理解
外鍵的理論定義是比較復(fù)雜的,我在以前公眾號寫過的一篇數(shù)據(jù)庫理論文章中有提及過,但是這一篇我們重點講解 MySQL 的使用,所以,我們把理論都換成例子和通俗的大白話,先來看個問題:
學(xué)生實體和課程實體分別用關(guān)系“學(xué)生”和“課程”來表示,它們之間的聯(lián)系用關(guān)系“選課”來表示
學(xué)生(學(xué)號,姓名,所在系,生日)課程(課程編號,課程名,授課老師)選課(學(xué)號,課程編號,成績)
問題:判斷各關(guān)系的候選鍵、主鍵、外鍵
答:
學(xué)生中(students) 學(xué)號可以確認(rèn)唯一的學(xué)生是候選鍵,可做主鍵,姓名需要在不重名的情況下也可以,但是實際情況不能保證沒有重名不合適,課程中(course) 課程編號可以確認(rèn)唯一的課程是候選鍵,可做主鍵,而選課中(sc_relation),需要由學(xué)號和課程編號共同才能確定唯一的值,所以兩者共同構(gòu)成候選鍵,并做主鍵
選課關(guān)系中的 學(xué)號(sc_relation.sid) 和 課程號(sc_relation.cid) ,分別代表選課關(guān)系的外鍵,他們分別對應(yīng) 學(xué)生關(guān)系的學(xué)號(students.sid) 和 課程關(guān)系的課程號(course.sid)(不一定要同名,但是為了好理解,一般寫成同名)
模擬了幾張簡單的表,給大家直觀的理解
說明:第一張為 學(xué)生表 students ,第二張為 課程表 course,第三張為 選課表 sc_relation
看完這個例子,是不是從理解上感覺清晰了很多,那么接下來,我們就實際操作一下:
C:基本格式
CREATE?TABLE?表名(????????....
????????CONSTRAINT?外鍵名稱?FOREIGN?KEY?(外鍵列名稱)?REFERENCES?主表名稱(主表列名稱)
);
--?創(chuàng)建表之后,刪除外鍵
ALTER?TABLE?表名?DROP?FOREIGN?KEY?外鍵名稱;
--?創(chuàng)建表之后,添加外鍵
ALTER?TABLE?表名?ADD?CONSTRAINT?外鍵名稱?FOREIGN?KEY?(外鍵字段名稱)?REFERENCES?主表名稱(主表列名稱);
B:具體操作
我們下面,就按照這張圖的規(guī)劃來做
創(chuàng)建學(xué)生表 students,學(xué)號 sid 為主鍵
????sid?INT(8)?PRIMARY?KEY?AUTO_INCREMENT,
????sname?VARCHAR(5)?NOT?NULL?UNIQUE,
????department?VARCHAR(32),
????birthday?date
);
創(chuàng)建課程表 course,課程號 cid 為主鍵
????cid?INT(8)?PRIMARY?KEY?AUTO_INCREMENT,
????cname?VARCHAR(5),
????teacher?VARCHAR(32)
);
創(chuàng)建選課關(guān)系表,sc_sid、sc_cid 分別為外鍵,指向?qū)W生表中的學(xué)號 sid 和 課程表中的課程號 cid
????sid?INT(8),
????cid?INT(8),
????cscore?VARCHAR(5),
????CONSTRAINT?sc_sid?FOREIGN?KEY?(sid)?REFERENCES?students(sid),
????CONSTRAINT?sc_cid?FOREIGN?KEY?(cid)?REFERENCES?course(cid)
);
隨便提供一些數(shù)據(jù),方便大家測試
--?插入學(xué)生數(shù)據(jù)INSERT?INTO?students?VALUES?(1001,?'王五',?'工商管理系',?'2020-06-16');
INSERT?INTO?students?VALUES?(1002,?'湯姆',?'音樂與舞蹈系',?'2020-06-16');
INSERT?INTO?students?VALUES?(1003,?'杰克',?'美術(shù)系',?'2020-06-16');
--?插入課程數(shù)據(jù)
INSERT?INTO?course?VALUES?(1,?'大學(xué)英語',?'老師1');
INSERT?INTO?course?VALUES?(2,?'大學(xué)物理',?'老師2');
INSERT?INTO?course?VALUES?(3,?'數(shù)據(jù)庫',?'老師3');
INSERT?INTO?course?VALUES?(4,?'操作系統(tǒng)',?'老師4');
INSERT?INTO?course?VALUES?(5,?'高等數(shù)學(xué)',?'老師5');
--?插入選課數(shù)據(jù)
INSERT?INTO?sc_relation?VALUES?(1001,?2,?'88');
INSERT?INTO?sc_relation?VALUES?(1001,?3,?'92');
INSERT?INTO?sc_relation?VALUES?(1001,?4,?'78');
INSERT?INTO?sc_relation?VALUES?(1001,?5,?'83');
INSERT?INTO?sc_relation?VALUES?(1002,?1,?'77');
INSERT?INTO?sc_relation?VALUES?(1002,?2,?'90');
INSERT?INTO?sc_relation?VALUES?(1002,?5,?'89');
INSERT?INTO?sc_relation?VALUES?(1003,?1,?'86');
INSERT?INTO?sc_relation?VALUES?(1003,?6,?'88');
INSERT?INTO?sc_relation?VALUES?(1003,?6,?'82');
有什么用呢?這個時候?qū)W生表以及課程表,就同選課表之間形成了關(guān)系,可視化軟件編輯插入的時候,就會默認(rèn)的給出一些可插入的選擇,這是軟件基于你設(shè)置的外鍵關(guān)系而自動尋找的
創(chuàng)建表后又怎么操作呢?
創(chuàng)建表之后,刪除外鍵
創(chuàng)建表之后,添加外鍵
C:級聯(lián)操作
如果在上述選課表中已經(jīng)存儲著 關(guān)于學(xué)號為 1001 學(xué)生的相關(guān)選課信息,如果這個時候,在學(xué)生表中修改或者刪除這條記錄,就會直接報錯
Cannot?add?or?update?a?child?row:?a?foreign?key?constraint?fails?(`mysql_grammar_test`.`sc_relation`,?CONSTRAINT?`sc_sid`?FOREIGN?KEY?(`sid`)?REFERENCES?`students`?(`sid`))所以我們使用級聯(lián)操作就可以達到同時更新或者刪除多張表內(nèi)的相關(guān)數(shù)據(jù)
先給出基本格式:
ALTER?TABLE?表名?ADD?CONSTRAINT?外鍵名稱?FOREIGN?KEY?(外鍵字段名稱)?REFERENCES?主表名稱(主表列名稱)?ON?UPDATE?CASCADE?ON?DELETE?CASCADE;A:級聯(lián)更新:ON UPDATE CASCADE
B:級聯(lián)刪除:ON DELETE CASCADE
例如測試一下
ALTER?TABLE?sc_relation?ADD?CONSTRAINT?sc_sid?FOREIGN?KEY?(sid)?REFERENCES?students(sid)?ON?UPDATE?CASCADE?ON?DELETE?CASCADE;之前不能操作的內(nèi)容,現(xiàn)在已經(jīng)可以了,例如我們在學(xué)生表中將 1001學(xué)號修改為 1008 ,這樣選課表中相關(guān)的內(nèi)容就會自動根據(jù)修改變化了哈
結(jié)尾
郵箱:ideal_bwh@163.com
如果能幫到你的話,那就來關(guān)注我吧!
如果您更喜歡微信文章的閱讀方式,可以關(guān)注我的公眾號
如果您更加喜歡PC端的閱讀方式,可以訪問我的個人博客
域名:www.ideal-20.cn
在這里的我們素不相識,卻都在為了自己的夢而努力 ?
一個堅持推送原創(chuàng)開發(fā)技術(shù)文章的公眾號:理想二旬不止
總結(jié)
以上是生活随笔為你收集整理的mysql约束_不是吧,阿Sir,MySQL约束你竟然还不懂!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 智慧城市_城市大脑:加速构建智慧城市
- 下一篇: mysql 游标总条数_mysql 游标