MySQL之senior(八)——約束
阿新 • • 發佈:2021-10-22
not null 與 unique
-
約束對應的英語單詞:constraint 在建立表的時候,我們可以給表中的欄位加上一些約束,來保證這個表中資料的完整性、有效性
-
約束包括哪些? 非空約束:not null 只有列級約束,沒有表級約束! 唯一性約束: unique unique約束的欄位不能重複,但是可以為NULL。 主鍵約束: primary key (簡稱PK) 外來鍵約束:foreign key(簡稱FK) 檢查約束:check(mysql不支援,oracle支援) 注意:
-
約束直接新增到列後面的,叫做列級約束
-
約束沒有新增在列的後面,這種約束被稱為表級約束。
-
unique:有列級約束,有表級約束
-
primary key: 有列級約束(推薦),有表級約束
-
需要給多個欄位聯合起來新增某一個約束的時候,需要使用表級約束。
-
在mysql當中,一個欄位同時被not null和unique約束,該欄位自動變成主鍵欄位。(oracle不是)
-
主鍵約束: primary key (PK)
-
主鍵: 主鍵值是每一行記錄的唯一標識。 主鍵值是每一行記錄的身份證號 任何一張表都應該有主鍵,沒有主鍵,表無效!! 主鍵的特徵:not null + unique(主鍵值不能是NULL,同時也不能重複!)
-
列級約束與表級約束
create table t_vip(
id int primary key, # 列級約束
name varchar(255),
);
create table t_vip(
id int,
name varchar(255),
primary key(id) # 表級約束
);
-
單一主鍵與複合主鍵
create table t_vip(
id int,
name varchar(255),
primary key(id) # 表級約束 單一主鍵
);
create table t_vip(
id int,
name varchar(255),
email varchar(255),
primary key(id,name) # 複合主鍵
);
# 在實際開發中不建議使用:複合主鍵。建議使用單一主鍵!
# 因為主鍵值存在的意義就是這行記錄的身份證號,只要意義達到即可,單一主鍵可以做到。
# 複合主鍵比較複雜,不建議使用
# 一張表,主鍵約束只能新增1個。
-
冷知識
主鍵除了:單一主鍵和複合主鍵之外,還可以這樣進行分類?
自然主鍵:主鍵值是一個自然數,和業務沒關係。
業務主鍵:主鍵值和業務緊密關聯,例如拿銀行卡賬號做主鍵值。這就是業務主鍵!
在實際開發中使用業務主鍵多,還是使用自然主鍵多一些?
自然主鍵使用比較多,因為主鍵只要做到不重複就行,不需要有意義。
業務主鍵不好,因為主鍵一旦和業務掛鉤,那麼當業務發生變動的時候,
可能會影響到主鍵值,所以業務主鍵不建議使用。儘量使用自然主鍵。
在mysql當中,有一種機制,可以幫助我們自動維護一個主鍵值?
create table t_vip(
id int primary key auto_increment, //auto_increment表示自增,從1開始,以1遞增!
name varchar(255)
);
外來鍵約束:foreign key(FK)
t_class 班級表
classno(pk) | classname |
---|---|
101 | 北京市大興區亦莊鎮第二中學高三1班 |
102 | 北京市大興區亦莊鎮第二中學高三2班 |
t_student 學生表
no(pk) | name | cno(FK引用t_class這張表的classno) |
---|---|---|
1 | lucy | 100 |
2 | lilei | 101 |
3 | hanme | 100 |
4 | lile | 100 |
5 | zhansan | 101 |
6 | lisi | 100 |
7 | wangwu | 101 |
8 | zhaoliu | 101 |
當cno欄位沒有任何約束的時候,可能會導致資料無效。可能出現一個102,但是102班級不存在。 所以為了保證cno欄位中的值都是100和101,需要給cno欄位新增外來鍵約束。 那麼:cno欄位就是外來鍵欄位。cno欄位中的每一個值都是外來鍵值。
注意:
t_class是父表 t_student是子表
刪除表的順序?
先刪子,再刪父。
建立表的順序?
先建立父,再建立子。
刪除資料的順序?
先刪子,再刪父。
插入資料的順序?
先插入父,再插入子。
create table t_student(
no int primary key auto_increment,
name varchar(255),
cno int,
foreign key(cno) references t_class(classno)
);
思考:子表中的外來鍵引用的父表中的某個欄位,被引用的這個欄位必須是主鍵嗎?
不一定是主鍵,但至少具有unique約束。
外來鍵值可以為NULL。