不是吧,阿Sir,MySQL常見約束你居然還不知道嗎?

之前寫的太亂了,翻出來從新整理下mysql

小系列目錄:sql

(一) MySQL入門,問題不大數據庫

https://segmentfault.com/a/11...segmentfault

(一) 引入約束

(1) 約束出如今哪裏?

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

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

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

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

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

(2) 約束用來幹嗎?

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

怎麼理解呢?就例如某一列叫作 學號,咱們就指定約束,這一行不容許爲 NULL ,同時咱們還能指定它爲主鍵,這樣經過學號就能夠查找到一條惟一的學生記錄了,還有例如外鍵知識等等...code

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

一樣,有了約束知識的鋪墊,咱們就能夠引伸出後面的一些知識,例如多表操做等等,因此約束雖然簡單,仍是很是重要的哈~

(二) 常見約束

(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 ,這樣選課表中相關的內容就會自動根據修改變化了哈

(三) 結尾

若是文章中有什麼不足,歡迎你們留言交流,感謝朋友們的支持!

若是能幫到你的話,那就來關注我吧!若是您更喜歡微信文章的閱讀方式,能夠關注個人公衆號

在這裏的咱們素不相識,卻都在爲了本身的夢而努力 ❤

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

相關文章
相關標籤/搜索