MySQL常見約束歸納總結【入門必看】

以前寫的太亂了,翻出來重新整理下

小系列目錄:

(一) MySQL入門,問題不大

https://blog.csdn.net/weixin_44652781/article/details/106466485

(一) 引入約束

(1) 約束出現在哪裏?

想要講解約束,就要知道約束用在哪裏,用來幹嘛?

SQL 語言通過定義一個關係所對應的基本表來完成關係模式的定義,其語句格式爲:

CREATE TABLE 表名(
	<列名1> <數據類型1> [<列級完整約束條件>],
	[<列名2> <數據類型2> [<列級完整約束條件>],...],
	[<表級完整約束條件>]
);

符號規定:下面展示一些定義的時候,爲簡便理解,使用中文配合符號表述(會有具體舉例,不用擔心理解不了)

  • <> 中的內容爲實際的語義
  • [] 中的內容爲任選項(不填寫也可)
  • {} 中的內容必須顯式的指定
  • | 爲選項符
  • [,...n] 表示前面的項可以重複多次

(2) 約束用來幹嘛?

約束,就是針對屬性值的一些約束條件,只針對某一列,叫做列級約束針對多列屬性的約束,叫做表級約束

怎麼理解呢?就例如某一列叫做 學號,我們就指定約束,這一行不允許爲 NULL ,同時我們還能指定它爲主鍵,這樣通過學號就可以查找到一條唯一的學生記錄了,還有例如外鍵知識等等…

總結起來就一句話:約束用來對錶中的數據進行限定,保證數據的正確性、有效性和完整性

同樣,有了約束知識的鋪墊,我們就可以引申出後面的一些知識,例如多表操作等等,所以約束雖然簡單,還是非常重要的哈~

(二) 常見約束

(1) 主鍵約束

A:基本概念

在關係模型中,主鍵的本質其實就是一個候選鍵

理解非常簡單,就是能通過這個主鍵,確定一個唯一的記錄:例如學號是學生實體的候選鍵,一個學號就能確定這個學生到底哪個學生,而我們不選擇姓名,這是因爲,姓名在實際的情況中,不能作爲一個唯一的標識,確認一個唯一的學生記錄

候選鍵:關係中能唯一標誌一個元組的最小屬性集

B:特點

確定爲主鍵的列,不能爲空,也不能重複!!!

C:具體操作

指定主鍵約束,使用的是 PRIMARY KEY 關鍵字

一般來說,主鍵約束主要用在創建表時,指定約束的方式有兩種:

  • ① 定義在列後
CREATE TABLE students  (
  sid INT(8) PRIMARY KEY,
  sname VARCHAR(5),
  department VARCHAR(32),
  birthday date
)
  • ② 獨立定義
CREATE TABLE students  (
  sid INT(8),
  sname VARCHAR(5),
  department VARCHAR(32),
  birthday date,
  PRIMARY KEY (sid) 
)

如果在表已經創建好的前提下,還可以通過下列兩種方式進行主鍵的指定和刪除

  • ① 刪除主鍵
ALTER TABLE students DROP PRIMARY KEY;
  • ② 指定主鍵
ALTER TABLE students ADD PRIMARY KEY(sid);

ALTER TABLE students MODIFY sid INT PRIMARY KEY;

D:主鍵自增

提到主鍵,就必須提到主鍵自增了,這個功能也是非常常用的,當設置主動自增後,例如你使用高級語言,操作數據庫,向學生表插入一條記錄後,即使不給出主鍵值,主鍵值也會自動生成出來,並且會在最大主鍵值的基礎上 + 1,例如 0,1,2 … ,n

最重要的一點,主鍵必須是整型,才能實現自增喔~

如果主鍵例如 sid 爲 varchar 類型,就會有這樣的報錯:Incorrect column specifier for column ‘sid’

同樣,主鍵自增一般用在創建表的時候,使用 AUTO_INCREMENT,直接跟在列名後即可

CREATE TABLE students  (
  sid INT(8) PRIMARY KEY AUTO_INCREMENT,
  sname VARCHAR(5),
  department VARCHAR(32),
  birthday date
)

如果表已經創建好了,還可以進行是否自增的修改

  • ① 設置主鍵自增
ALTER TABLE students CHANGE sid sid INT AUTO_INCREMENT;

ALTER TABLE students MODIFY sid INT AUTO_INCREMENT;
  • ② 刪除主鍵自增
ALTER TABLE students CHANGE sid sid INT;

ALTER TABLE students MODIFY sid INT;

說明:上面設置以及刪除都給出了 CHANGE 和 MODIFY 兩種,有什麼區別呢?

其實細心的朋友也可以看出來, CHANGE 後要多一個列名 sid(可以修改) ,所以總結如下:

  • 只修改類型用 MODIFY
  • 既修改列名,也修改類型用 CHANGE

(2) 非空約束

非空約束很好理解,就是指定非空約束列的值不能爲空,我們使用 NOT NULL 來實現這個功能

CREATE TABLE students  (
  sid INT(8) PRIMARY KEY AUTO_INCREMENT,
  sname varchar(5) NOT NULL, -- sname 不爲空
  department varchar(32),
  birthday date
);

很簡單吧,我們已經將 sname 這個字段(列)在創建時添加了非空約束,如果 sname 在插入時爲NULL ,則會報錯 Column ‘sname’ cannot be null

如果表已經創建好了怎麼辦呢?

  • 創建表完後,添加非空約束
ALTER TABLE students MODIFY sname VARCHAR(5) NOT NULL;
  • 刪除 sname 的非空約束
ALTER TABLE students MODIFY sname VARCHAR(5);

(3) 唯一約束

唯一約束,就是指定這個字段(列)的值必須是唯一的,這種感覺就類似主鍵,例如我們下面要求創建表的時候,指定 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’

同樣,如果已經創建表後,又該怎麼設置或者刪除唯一約束呢?

  • 在創建表後,添加唯一約束
ALTER TABLE students MODIFY sname VARCHAR(8) UNIQUE;
  • 刪除唯一約束(本質上就是刪除索引)
ALTER TABLE students DROP INDEX sname;
-- 這兩種方法都是可以的
drop index sname on students;

(4) 外鍵約束

A:概念理解

外鍵的理論定義是比較複雜的,我在以前公衆號寫過的一篇數據庫理論文章中有提及過,但是這一篇我們重點講解 MySQL 的使用,所以,我們把理論都換成例子和通俗的大白話,先來看個問題:

學生實體和課程實體分別用關係“學生”和“課程”來表示,它們之間的聯繫用關係“選課”來表示

學生(學號,姓名,所在系,生日)
課程(課程編號,課程名,授課老師)
選課(學號,課程編號,成績)

問題:判斷各關係的候選鍵、主鍵、外鍵

答:

  • 學生中(students) 學號可以確認唯一的學生是候選鍵,可做主鍵,姓名需要在不重名的情況下也可以,但是實際情況不能保證沒有重名不合適,課程中(course) 課程編號可以確認唯一的課程是候選鍵,可做主鍵,而選課中(sc_relation),需要由學號和課程編號共同才能確定唯一的值,所以兩者共同構成候選鍵,並做主鍵
  • 選課關係中的 學號(sc_relation.sid)課程號(sc_relation.cid) ,分別代表選課關係的外鍵,他們分別對應 學生關係的學號(students.sid)課程關係的課程號(course.sid)(不一定要同名,但是爲了好理解,一般寫成同名)
  • 模擬了幾張簡單的表,給大家直觀的理解
    • 說明:第一張爲 學生表 students ,第二張爲 課程表 course,第三張爲 選課表 sc_relation

看完這個例子,是不是從理解上感覺清晰了很多,那麼接下來,我們就實際操作一下:

C:基本格式

CREATE TABLE 表名(
		....
		CONSTRAINT 外鍵名稱 FOREIGN KEY (外鍵列名稱) REFERENCES 主表名稱(主表列名稱)
);

-- 創建表之後,刪除外鍵
ALTER TABLE 表名 DROP FOREIGN KEY 外鍵名稱;

-- 創建表之後,添加外鍵
ALTER TABLE 表名 ADD CONSTRAINT 外鍵名稱 FOREIGN KEY (外鍵字段名稱) REFERENCES 主表名稱(主表列名稱);

B:具體操作

我們下面,就按照這張圖的規劃來做

  • 創建學生表 students,學號 sid 爲主鍵
CREATE TABLE students (
    sid INT(8) PRIMARY KEY AUTO_INCREMENT,
	sname VARCHAR(5) NOT NULL UNIQUE,
	department VARCHAR(32),
	birthday date
);
  • 創建課程表 course,課程號 cid 爲主鍵
CREATE TABLE course (
	cid INT(8) PRIMARY KEY AUTO_INCREMENT,
	cname VARCHAR(5),
	teacher VARCHAR(32)
);
  • 創建選課關係表,sc_sid、sc_cid 分別爲外鍵,指向學生表中的學號 sid 和 課程表中的課程號 cid
CREATE TABLE sc_relation  (
	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)
);

隨便提供一些數據,方便大家測試

-- 插入學生數據
INSERT INTO students VALUES (1001, '王五', '工商管理系', '2020-06-16');
INSERT INTO students VALUES (1002, '湯姆', '音樂與舞蹈系', '2020-06-16');
INSERT INTO students VALUES (1003, '傑克', '美術系', '2020-06-16');

-- 插入課程數據
INSERT INTO course VALUES (1, '大學英語', '老師1');
INSERT INTO course VALUES (2, '大學物理', '老師2');
INSERT INTO course VALUES (3, '數據庫', '老師3');
INSERT INTO course VALUES (4, '操作系統', '老師4');
INSERT INTO course VALUES (5, '高等數學', '老師5');

-- 插入選課數據
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');

有什麼用呢?這個時候學生表以及課程表,就同選課表之間形成了關係,可視化軟件編輯插入的時候,就會默認的給出一些可插入的選擇,這是軟件基於你設置的外鍵關係而自動尋找的

創建表後又怎麼操作呢?

  • 創建表之後,刪除外鍵
ALTER TABLE sc_relation DROP FOREIGN KEY sc_sid;
  • 創建表之後,添加外鍵
ALTER TABLE sc_relation ADD CONSTRAINT sc_sid FOREIGN KEY (sid) REFERENCES students(sid)

C:級聯操作

如果在上述選課表中已經存儲着 關於學號爲 1001 學生的相關選課信息,如果這個時候,在學生表中修改或者刪除這條記錄,就會直接報錯

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`))

所以我們使用級聯操作就可以達到同時更新或者刪除多張表內的相關數據

先給出基本格式:

ALTER TABLE 表名 ADD CONSTRAINT 外鍵名稱 FOREIGN KEY (外鍵字段名稱) REFERENCES 主表名稱(主表列名稱) ON UPDATE CASCADE ON DELETE CASCADE;
  • A:級聯更新:ON UPDATE CASCADE
  • B:級聯刪除:ON DELETE CASCADE

例如測試一下

ALTER TABLE sc_relation ADD CONSTRAINT sc_sid FOREIGN KEY (sid) REFERENCES students(sid) ON UPDATE CASCADE ON DELETE CASCADE;

之前不能操作的內容,現在已經可以了,例如我們在學生表中將 1001學號修改爲 1008 ,這樣選課表中相關的內容就會自動根據修改變化了哈

(三) 結尾

如果文章中有什麼不足,歡迎大家留言交流,感謝朋友們的支持!

如果能幫到你的話,那就來關注我吧!如果您更喜歡微信文章的閱讀方式,可以關注我的公衆號

在這裏的我們素不相識,卻都在爲了自己的夢而努力 ❤

一個堅持推送原創開發技術文章的公衆號:理想二旬不止

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章