1. 程式人生 > 實用技巧 >MySQL基礎-17DDL語言(資料定義語言)-常見約束

MySQL基礎-17DDL語言(資料定義語言)-常見約束

宣告:此MySQL基礎學習源自尚矽谷。(推薦)b站官方連結:https://www.bilibili.com/video/BV1xW411u7ax?p=1

常見約束

含義:一種限制,用於限制表中的資料,為了保證表中的資料的準確和可靠性


分類:六大約束
	NOT NULL:非空,用於保證該欄位的值不能為空
	比如姓名、學號等
	
	DEFAULT:預設,用於保證該欄位有預設值
	比如性別
	
	PRIMARY KEY:主鍵,用於保證該欄位的值具有唯一性,並且非空   /'praɪ m(ə) rɪ/主要的
	比如學號、員工編號等
	
	UNIQUE:唯一,用於保證該欄位的值具有唯一性,可以為空   /juː' niː k/唯一的
	比如座位號
	
	CHECK:檢查約束【mysql中不支援】
	比如年齡、性別
	
	FOREIGN KEY:外來鍵,用於限制兩個表的關係,用於保證該欄位的值必須來自於主表的關聯列的值 /'fɒrɪn/外交的
		在從表新增外來鍵約束,用於引用主表中某列的值
		比如學生表的專業編號,員工表的部門編號,員工表的工種編號
	

新增約束的時機:
	1.建立表時
	2.修改表時
	(資料新增之前)

約束的新增分類:
	列級約束:
		建立表時在欄位後面新增的約束(六大約束語法上都支援,但外來鍵約束沒有效果)
		如:CREATE TABLE 表名(
			欄位名 欄位型別 列級約束,
			欄位名 欄位型別,
			表級約束
		)
		
	表級約束:
		在建立表時約束沒有在任何欄位後面,不屬於任何欄位,在表最後面。
		(除了非空、預設,其他的都支援)
		如:CREATE TABLE 表名(
			欄位名 欄位型別 列級約束,
			欄位名 欄位型別,
			表級約束
		)
外來鍵:
	1、要求在從表設定外來鍵關係
	2、從表的外來鍵列的型別和主表的關聯列的型別要求一致或相容,名稱無要求
	3、主表的關聯列必須是一個key(一般是主鍵或唯一)
	4、插入資料時,先插入主表,再插入從表
		刪除資料時,先刪除從表,再刪除主表
		
# 直接刪除從表資料,會報錯,因為有外來鍵關聯
delete from major where id=3;
# 報錯資訊:
查詢:delete from major where id=3錯誤程式碼:1451
Cannot delete or update a parent row:a foreign key constraint fails ('students','stuinfo',CONSTRAIINT 'fk_stu_major' FOREIGN KEY ('majorid') REFERENCES 'major' ('id'))
-- 可以通過以下兩種方式來刪除主表的記錄

#方式一:級聯刪除,新增外來鍵時新增級聯刪除
# 刪除從表資料時,主表與從表關聯的資料也會刪除
ALTER TABLE stuinfo ADD CONSTRAINT fk_stu_major FOREIGN KEY(majorid) REFERENCES major(id) ON DELETE CASCADE; # ON DELETE CASCADE級聯刪除

#方式二:級聯置空
# 刪除主表資料時,從表與主表關聯的資料項會被置為null
ALTER TABLE stuinfo ADD CONSTRAINT fk_stu_major FOREIGN KEY(majorid) REFERENCES major(id) ON DELETE SET NULL; # ON DELETE SET NULL級聯置空

主鍵和唯一的大對比:

保證唯一性 是否允許為空 一個表中可以有多少個 是否允許組合
主鍵 × 至多一個(可以沒有) √(不推薦)
唯一 可以多個 √(不推薦)

唯一約束在表中只允許存在一個null

新增表級約束時可以設定組合主鍵、組合唯一鍵
CREATE TABLE stuinfo(
	id INT,
	stuname VARCHAR(20),
	gender CHAR(1), # 逗號與表級約束分隔
	
	CONSTRAINT pk PRIMARY KEY(id,stuname), # 設定組合主鍵
	CONSTRAINT uq UNIQUE(stuname,gender),# 設定組合唯一鍵
);
/*
設定id、stuname兩個欄位為組合主鍵,只要保證其中一個不同即可
如:
id=1,stuname='aa' <--> id=1,stuname='bb'  資料儲存成功
id=1,stuname='aa' <--> id=2,stuname='aa'  資料儲存成功
id=1,stuname='aa' <--> id=2,stuname='bb'  資料儲存成功

id=1,stuname='aa' <--> id=1,stuname='aa'  資料儲存失敗
*/

1.建立表時新增約束

1.新增列級約束

語法:
直接在欄位名和型別後面追加 約束型別即可。

只支援:預設、非空、主鍵、唯一
USE students;
DROP TABLE stuinfo;
CREATE TABLE stuinfo(
	id INT PRIMARY KEY,#主鍵
	stuName VARCHAR(20) NOT NULL UNIQUE,#非空  一個欄位可以設定多個約束,空格隔開
	gender CHAR(1) CHECK(gender='男' OR gender ='女'),#檢查
	seat INT UNIQUE,#唯一
	age INT DEFAULT  18,#預設約束
	majorId INT REFERENCES major(id)#外來鍵(沒效果)  /'refərənsɪz/ 

);

CREATE TABLE major(
	id INT PRIMARY KEY,
	majorName VARCHAR(20)
);

desc stuinfo; # 查看錶結構
SHOW INDEX FROM stuinfo; # 檢視stuinfo中的所有索引,包括主鍵、外來鍵、唯一

2.新增表級約束

語法:在各個欄位的最下面,與列級約束之間用逗號分隔
 【constraint 約束名】 約束型別(欄位名)   /kənˈ str eɪ nt/約束
 不自定約束名,預設名是欄位名
 
 除了非空、預設,其他的都支援
 
 一個表可以新增多個外來鍵
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
	id INT,
	stuname VARCHAR(20),
	gender CHAR(1),
	seat INT,
	age INT,
	majorid INT, # 逗號與表級約束分隔
	
	CONSTRAINT pk PRIMARY KEY(id),#主鍵  pk:自定義主鍵約束名(任意起名)
	CONSTRAINT uq UNIQUE(seat),#唯一鍵  pk:自定義唯一鍵約束名(任意起名)
	CONSTRAINT ck CHECK(gender ='男' OR gender  = '女'),#檢查
    # 非空、預設約束不支援表級約束
	CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外來鍵

);

SHOW INDEX FROM stuinfo;

通用的寫法:★

CREATE TABLE IF NOT EXISTS stuinfo(
	id INT PRIMARY KEY,
	stuname VARCHAR(20),
	sex CHAR(1),
	age INT DEFAULT 18,
	seat INT UNIQUE,
	majorid INT,
	CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)
			# 一般外來鍵名定義: fk(外來鍵縮寫)_當前表名_主表名
    		# 一個表可以新增多個外來鍵,這樣定義易於區分
);

2.修改表時新增約束

1、新增列級約束
alter table 表名 modify column 欄位名 欄位型別 新約束;

2、新增表級約束
alter table 表名 add 【constraint 約束名】 約束型別(欄位名) 【外來鍵的引用】;
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
	id INT,
	stuname VARCHAR(20),
	gender CHAR(1),
	seat INT,
	age INT,
	majorid INT
)
DESC stuinfo;

1.新增非空約束

ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20)  NOT NULL;
# 刪除非空約束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20)  NULL;
或者
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20);

2.新增預設約束

ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;

3.新增主鍵

#①列級約束
ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;

#②表級約束
ALTER TABLE stuinfo ADD PRIMARY KEY(id);

4.新增唯一

#①列級約束
ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;

#②表級約束
ALTER TABLE stuinfo ADD UNIQUE(seat);

5.新增外來鍵

ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id); 

3.修改表時刪除約束

1.刪除非空約束

ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;
# (最後面的null可以寫也可以不寫,預設為null)

2.刪除預設約束

ALTER TABLE stuinfo MODIFY COLUMN age INT ;

3.刪除主鍵

ALTER TABLE stuinfo DROP PRIMARY KEY;  # (直接加drop 約束名 刪除約束)

4.刪除唯一

ALTER TABLE stuinfo DROP INDEX seat;

5.刪除外來鍵

ALTER TABLE stuinfo DROP FOREIGN KEY fk_stuinfo_major;

SHOW INDEX FROM stuinfo;

列級約束與表級約束區別:

位置 支援的約束型別 是否可以起約束名
列級約束 列的後面 語法都支援,但外來鍵沒有效果 不可以
表級約束 所有列的下面(逗號分隔) 預設和非空不支援,其他支援 可以(主鍵沒有效果)