一、外鍵前戲
如果我們把所有的信息都記錄在一張表中會帶來的問題:
1.表的結構不清晰
2.浪費磁盤空間
3.表的擴展性極差
所以我們要把這種表拆成幾張不同的表,分析表與表之間的關系。
確定表與表之間的關系,一定要換位思考(必須兩方都考慮周全之后才能得出結論)
學生與班級表:
1.站在學生的角度看班級:能否多個學生在一個班級 (一個班級能否有多個學生) 可以!!!
2.站在班級的角度看學生:能否有多個班級對應一個學生 (一個學生能否在多個班級) 不可以!!!
結論:學生表和班級表之間僅僅只是單向的多對一,那么它們的關系就是“一對多”(無論是多對一還是一對多,都叫‘一對多’)
所以學生表多對一班級表,在學生表中創建一個字段(class_id)指向班級表的id字段。
如何讓兩種表有代碼層面上真正的關聯,就必須使用外鍵 (foreign key)
什么是外鍵? 讓表與表有硬性層面上的關系。
二、一對多
foreign key
外鍵約束
1.在創建表的時候,必須先創建被關聯表
2.插入數據的時候,也必須先插入被關聯表的數據
有員工表和部門表,之間是一對多的關系,通常將關系字段稱之為外鍵字段,外鍵建在多的一方。(這里外鍵建在員工表中)
建表:
先建部門表(被關聯表)
#部門表 create table dep( id int primary key auto_increment, dep_name varchar(20), dep_sec varchar(20) );
創建員工表 除了基本的員工字段,還有一個外鍵和部門表的id字段綁定關系
#員工表 create table emp( id int primary key auto_increment, emp_name varchar(10), emp_gender enum('male','female','others') default 'male', dep_id int, foreign key(dep_id) references dep(id) #dep_id是外鍵字段並且和dep表id字段有關系 );
插入數據:
部門表先插數據
insert into dep(dep_name,dep_desc) values('技術部','提供技術服務'), ('后勤部','后勤保障'), ('財務部','發工資');
員工表插數據 這里需要注意的點是你插入的dep_id一定要是部門表中存在的,否則就會報錯
insert into emp(emp_name,dep_id) values('jason',1), ('egon',2), ('tank',3);
修改表數據:
外鍵雖然能夠幫你強制建立關系,但是也會給表之間增加數據相關的約束。
1.在刪除數據的時候,要先刪除員工表的數據,才能刪除部門表的數據。
因為員工表中有外鍵關聯字段部門表,所以直接刪部門表的數據會報錯
2.可以使用級聯更新和級聯刪除
在外鍵加上 on update cascade on delete cascade
#員工表 create table emp( id int primary key auto_increment, emp_name varchar(10), emp_gender enum('male','female','others') default 'male', dep_id int, foreign key(dep_id) references dep(id) #dep_id是外鍵字段並且和dep表id字段有關系 on update cascade on delete cascade );
update dep set id=200 where id = 3;
delete from dep where id = 2;
三、多對多
圖書與作者表 換位思考
1.先站在圖書表:多本書能否是有一個作者(一個作者能否寫多本圖書 ) 可以!!!
2.站在作者表:多個作者能否合寫一本書(一本書能否有多個作者) 可以!!!
如果雙方都是可以,那么就是多對多
強調!!! foreign key只是用來幫你建表關系的,不是某個關系特有的方法
多對多關系的建立,必須手動創建第三張表,用來專門記錄兩種表之間的關系
建表
先建兩種普通的表,不需要設置外鍵
圖書表
create table book( id int primary key auto_increment, title varchar(10), price int );
作者表
create table author( id int primary key auto_increment, name varchar(20), age int );
關聯表 兩個外鍵(一個book_id關聯book表的id字段,一個author_id關聯author表的id字段)
create table book2author(
id int primary key auto_increment,
book_id int, foreign key(book_id) references book(id) on update cascade on delete cascade,
author_id int, foreign key(author_id) references author(id) on update cascade on delete cascade
);
插入數據
圖書表插入數據:
insert into book(title,price) values('西游記',50),('水滸傳',80),('紅樓夢',60);
作者表插入數據:
insert into author(name,age) values('小紅',30),('小蘭',40),('小綠',50);
關聯表插入數據:
insert into book2author(book_id,author_id) values(1,1),(1,2),(2,1),(1,2),(3,1);
四、一對一關系
一對一的場景,當你的表特別龐大的時候,你可以考慮拆分表
比如一張表里面有客戶基本信息(名字,年齡),還有詳細(愛好,身高,身份證號。。。)
外鍵字段建在任意一方都可以,但是推薦你建在查詢頻率高的一方
建表
用戶表:因為用戶表中含有外鍵所以應該先建用戶詳細表
create table user( id int primary key auto_increment, name varchar(10), age int,
userdetail_id int unique, #唯一,一對一關系
foreign key(userdetail_id) references userdetail(id)
on update cascade
on delete cascade );
用戶詳細表
create table userdetail( id int primary key auto_increment, hobby varchar(20), IDcard varchar(20) );
總結:
1.通常將關系字段稱之為外鍵字段
一對多的外鍵字段,建在多的一方
多對多的外鍵字段,建在第三張表
一對一,外鍵字段建在任意一方都可以,推薦建在查詢頻率高的那邊
2.判斷表關系的最簡單的方法:
圖書與出版社
一本書可不可以有多個出版社 不可以!!!
一個出版社可不可以出多本書 可以!!!
一對多的關系
圖書與作者表
一本書可不可以有多個作者 可以!!!
一個作者可不可以出多本書 可以!!!
多對多的關系
作者與作者詳情
一個作者可不可以有多個詳情 不可以!!!
一個作者詳情可不可以有多個作者 不可以!!!
要么兩者是一對一,要么兩者之間沒有關系
了解知識點:
修改表
1.修改表的完整語句 1. 修改表名 ALTER TABLE 表名 RENAME 新表名; 2. 增加字段 ALTER TABLE 表名 ADD 字段名 數據類型 [完整性約束條件…], ADD 字段名 數據類型 [完整性約束條件…]; #插入多條 ALTER TABLE 表名 ADD 字段名 數據類型 [完整性約束條件…] FIRST; # 直接移到最前面 ALTER TABLE 表名 ADD 字段名 數據類型 [完整性約束條件…] AFTER 字段名; # 尋找插哪個字段的后面 3. 刪除字段 ALTER TABLE 表名 DROP 字段名; 4. 修改字段 # modify只能改字段數據類型完整約束,不能改字段名,但是change可以! ALTER TABLE 表名 MODIFY 字段名 數據類型 [完整性約束條件…]; ALTER TABLE 表名 CHANGE 舊字段名 新字段名 新數據類型 [完整性約束條件…]; 復制表 # 查詢語句執行的結果也是一張表,可以看成虛擬表 # 復制表結構+記錄 (key不會復制: 主鍵、外鍵和索引) create table new_service select * from service; #復制
# 只復制表結構 select * from service where 1=2; //條件為假,查不到任何記錄 create table new1_service select * from service where 1=2; create table t4 like employees;