一、約束的定義
MySQL 約束是用于限制表中數據的規則,確保數據的 準確性 和 一致性 。約束可以在創建表時定義,也可以在表創建后通過修改表結構添加。
二、常見的約束類型
2.1 NOT NULL 非空約束
加了非空約束的列不能為 NULL 值,如果可以預見某個列不可能為空,例如(性別:男 或 女 或者 保密)建議都加上非空約束,有利于查詢效率的提高
這里創建一個 student 表,沒有添加任何約束
我們可以往表里添加 NULL 數據,但這是無意義的
接下來通過修改表給 name 列添加上非空約束
數據庫報錯:不能對已經有 NULL 的列添加 非空約束
可以通過將帶有 NULL 的數據刪除或者將列刪除重新創建來進行修改嗎?
這里選擇刪除列后再重新創建,再嘗試往 name 列里添加 NULL
數據庫報錯:'name' 列不能為空
對表進行查看可以看到 name 的 NULL 列變成 NO 了
但是數據依然存在,所以還是需要通過 刪除數據 來進行修改,但數據量大時也不方便。所以最好還是在一開始創建表時就對每個數據做好分析,提前選擇好約束
2.2 DEFAULT 默認值約束
當某個列沒有被插入指定數據時則為默認值
插入數據時注意不能使用全列插入
數據庫報錯:列的數量和輸入值的數量不一致
只能使用指定列插入才可以
查看表可以看到,hobby 列的 DEFAULT 的被修改為了 '無'
2.3?UNIQUE 唯一約束
當我們遇到需要存入不能重復的數據時(例如:身份證號,學號等等)就可以使用 UNIQUE 來指定唯一約束的列
添加約束前
將 id 列添加 UNIQUE 約束后再進行添加數據
數據庫報錯:添加鍵中的值 1 與列中值重復
注意:只添加了 UNIQUE 的列可以寫入多個 NULL
查看表可以看到,id?列的 KEY?的添加了 UNI 表示不可重復
2.4 PRIMARY KEY 主鍵約束
主鍵約束唯一標識數據庫表中的每條幾率,可以理解為當前數據行的身份信息
主鍵必須包含唯一的值,且不能包含 NULL 的值(唯一且非空)
- 既然是唯一且非空是否能用 id int unique not null 來代替主鍵呢?答案是不可以的,這里要區分開unique not null 是業務對數據本身的需求,primary key則是表的特性,數據如何組織依賴主鍵
通常為每張表指定一個主鍵,主鍵列建議使用 BIGINT 類型(范圍夠大)
重新創建表 student
查看表可以看到,id 列的 Key 變為了 PRI
因為 PRIMARY KEY 的特性一般把主鍵設為自動增長 (auto_increment),插入數據對應字段不給值時,使用最大值+1。
語法:
id INT PRIMARY KEY auto_increment,
可以看到 Extra 處已經有了 自增標識,寫入數據時就不用人為的去維護主鍵值。
可以使用指定列插入
也可以用全列插入,但是需要指定為值為 NULL(并不是為空,而是讓數據庫去填寫)
可以通過命令 show create table 表名?來查看表的具體信息
這里的 AUTO_INCREMENT = 4 是告訴我們下個存入的數據 ID 會等于 4,如果已經設置了自動增長還主題設置 ID 值呢?數據是可以被正常添加的
AUTO_INCREMENT 的值會來到101,如果再添加一個 ID 為 4 的值,也是能正常添加的
但是 AUTO_INCREMENT 的值不會再變小,這是基于對數據的安全考慮,中間浪費的區間也能是浪費了。
每個表只能有一個主鍵,可以由單個列或者多個列組成。還是重新創建一個 student 表,通過PRIVARY KEY(列名1,列名2...)來指定主鍵,多個列組成的主鍵稱作 復合主鍵
復合主鍵中的每一列不能同時相等
主鍵或唯一鍵沖突時的更新操作,插入否則更新
語法:
INSERT ... ON DUPLICATE KEY UPDATE column = value [, column = value] ...
可以看到這里的更新操作針對兩行進行了操作,刪除了原來的行,又新增了一條記錄。如果主鍵沒有沖突則新增一條直接記錄。
在實際開發中不建議直接替換老數據:
- 先按條件查詢一下數據,有沒有相應的記錄
- 沒有的話就 insert 一條新記錄
- 有的話,要么做 update 操作,要么把原數據的刪除標識置為已刪除,再寫一條新數據
2.5 FOREIFN KEY 外鍵約束
外鍵用于定義主表和從表之間的關系
外鍵約束定義在從表的列上,主表關聯的列必須是主鍵或唯一約束
當定義外鍵后,要求從表中的外鍵列數據必須在主表的主鍵或唯一列存在或為 null
主要作用:
- 確保引用完整:防止從表引用不存在的主表記錄,確保數據邏輯關系正確;
- 維護數據一致:當主表數據變更時,數據庫可以自動處理子表相關數據;
- 防止孤立記錄:會阻止刪除被引用的主表記錄,避免子表記錄因主表刪除或修改導致變成“孤立記錄”;
- 優化查詢性能:這樣的設計方法可以減少許多不必要數據的冗余。
語法:
foreign key (class_id) references class (id)
實例:
創建一個班級表 class , id 為主鍵
創建一個學生表,一個學生對應一個班級,一個班級對應多個學生,用 id?為主鍵,class_id 為外鍵,關聯表 id
再在表中插入數據
當我們插入引用不存在的數據或是對主表中數據進行刪除時
數據庫都會進行報錯:不能刪除這一行,有一個外鍵約束
如果希望實現當主表修改時,從表自動更新,需要在約定外鍵時,補充??ON DELETE CASCADE
FOREIGN KEY 外鍵 REFERENCES 主鍵 ON DELETE CASCADE
如果外鍵約束的特性,刪改一定要先刪除從表中的數據,導致在實際工作中一般不使用,可以通過在 JAVA 層面處理關聯關系,保證數據正確后再入庫
2.6 CHECK 約束
引用于一個或多個列,用于限制列中可接受的數據值,從而確保數據的完整性和準確性
這里創建了一個 teacher 表,同時對表中的 gender 做了約束,規定只能為 男 或者 女
當我們使用規定之外的詞就會進行報錯,約束之內就可以正常輸入
列與列直接也可以比較,需要在單獨一行定義
示例:
CREATE TABLE t_check (c1 int check(c1 <> 0),c2 int check(c2 > 0),c3 int,check(c3 >= c2)
);