MySQL表關系--外鍵


一、外鍵前戲

如果我們把所有的信息都記錄在一張表中會帶來的問題:

  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;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM