數據庫之表關系,一對多、多對多、一對一(外鍵,級聯更新級聯刪除)



如何讓兩種表有代碼層面上真正的關聯 就必須使用外鍵
什么是外鍵?
讓表與表有硬性層面上的關系


一對多(Foreign Key)
foreign key
外鍵約束
1.在創建表的時候 必須先創建被關聯表
2.插入數據的時候 也必須先插入被關聯表的數據

#部門表
id dep_name dep_sesc
1 技術部 技術支持
2 管理部 公司經營管理
3 銷售部 負責產品的銷售和后期的客戶關系維護
4 咨詢部 公司產品介紹


#先創建被關聯表
create table dep(
id int primary key auto_increment,
dep_name varchar(32),
dep_desc varchar(128)
);

#再創建關聯表
create table emp(
id int primary key auto_increment,
emp_name varchar(16),
emp_gender enum('male','female','others') default 'male',
dep_id int,
foreign key(dep_id) references dep(id)
);

#先插入被關聯表的數據

insert into dep(dep_name,dep_desc) values('技術部','技術支持'),
('管理部','公司經營管理'),
('銷售部','負責產品的銷售和后期的客戶關系維護'),
('咨詢部','公司產品介紹');

#再插入關聯表的數據

insert into emp(emp_name,dep_id) values('張三',1),('李四',2),('王五',3),('小紅',4),('小麗',4),('小明',2);


update dep set id=5 where id=2; #不能更改
'''
mysql> update dep set id=5 where id=2;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`db3`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`dep_id`) REFERENCES `dep` (`id`))

'''

update emp set id=100 where id=2; #可以更改
'''
mysql> update emp set id=100 where id=2;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
'''


delete dep from where id=1; #,在沒有先刪除對應員工表數據時,被關聯的部門不能刪除
####
mysql> delete from dep where id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`db3`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`dep_id`) REFERENCES `dep` (`id`))
mysql> update emp set id=2 where id=100;
#####


外鍵雖然能夠幫你強制建立表關系 但是也會給表之間增加數據相關的約束
1.刪除數據的時候 先刪員工表的數據 再刪部門表的數據
delete from emp where id=2;
delete from emp where id=6;
'''
mysql> delete from emp where id=2;
Query OK, 1 row affected (0.05 sec)

mysql> delete from emp where id=6;
Query OK, 1 row affected (0.06 sec)

mysql> select * from emp;
+----+----------+------------+--------+
| id | emp_name | emp_gender | dep_id |
+----+----------+------------+--------+
| 1 | 張三 | male | 1 |
| 3 | 王五 | male | 3 |
| 4 | 小紅 | male | 4 |
| 5 | 小麗 | male | 4 |
+----+----------+------------+--------+
'''
===============================================

delete from dep where id=2;

'''
mysql> delete from dep where id=2;
Query OK, 1 row affected (0.06 sec)

mysql> select * from dep;
+----+-----------+-----------------------------------------------------+
| id | dep_name | dep_desc |
+----+-----------+-----------------------------------------------------+
| 1 | 技術部 | 技術支持 |
| 3 | 銷售部 | 負責產品的銷售和后期的客戶關系維護 |
| 4 | 咨詢部 | 公司產品介紹 |
+----+-----------+-----------------------------------------------------+
3 rows in set (0.00 sec)
'''

級聯更新級聯刪除
刪除部門后,對應的部門里面的員工表數據對應刪除
更新部門后,對應員工表中的標示部門的字段同步更新

create table dep1(
id int primary key auto_increment,
dep_name varchar(32),
dep_desc varchar(128)
);

create table emp1(
id int primary key auto_increment,
emp_name varchar(32),
emp_gender enum('male','female','others') default 'male',
dep_id int,
foreign key(dep_id) references dep1(id)
on update cascade
on delete cascade
);


insert into dep1(dep_name,dep_desc) values ('技術部','技術支持'),
('管理部','公司經營管理'),
('銷售部','負責產品的銷售和后期的客戶關系維護'),
('咨詢部','公司產品介紹');
'''
mysql> select * from dep1;
+----+-----------+-----------------------------------------------------+
| id | dep_name | dep_desc |
+----+-----------+-----------------------------------------------------+
| 1 | 技術部 | 技術支持 |
| 2 | 管理部 | 公司經營管理 |
| 3 | 銷售部 | 負責產品的銷售和后期的客戶關系維護 |
| 4 | 咨詢部 | 公司產品介紹 |
+----+-----------+-----------------------------------------------------+
4 rows in set (0.00 sec)
'''

insert into emp1(emp_name,dep_id) values('張三',1),('李四',2),
('王五',3),('小紅',4),('小麗',4),('小明',2);
'''
mysql> select * from emp1;
+----+----------+------------+--------+
| id | emp_name | emp_gender | dep_id |
+----+----------+------------+--------+
| 1 | 張三 | male | 1 |
| 2 | 李四 | male | 2 |
| 3 | 王五 | male | 3 |
| 4 | 小紅 | male | 4 |
| 5 | 小麗 | male | 4 |
| 6 | 小明 | male | 2 |
+----+----------+------------+--------+
6 rows in set (0.00 sec)
'''

update dep1 set id=200 where id=1;
'''
mysql> select * from dep1;
+-----+-----------+------------------------------------
| id | dep_name | dep_desc
+-----+-----------+------------------------------------
| 2 | 管理部 | 公司經營管理
| 3 | 銷售部 | 負責產品的銷售和后期的客戶關系維護
| 4 | 咨詢部 | 公司產品介紹
| 200 | 技術部 | 技術支持
+-----+-----------+------------------------------------
4 rows in set (0.00 sec)

mysql> select * from emp1;
+----+----------+------------+--------+
| id | emp_name | emp_gender | dep_id |
+----+----------+------------+--------+
| 1 | 張三 | male | 200 |
| 2 | 李四 | male | 2 |
| 3 | 王五 | male | 3 |
| 4 | 小紅 | male | 4 |
| 5 | 小麗 | male | 4 |
| 6 | 小明 | male | 2 |
+----+----------+------------+--------+
'''

delete from dep1 where id=2;
# 刪除id=2 管理部消失,關聯的員工表中李四和小明兩條信息也自動被清除了。
'''
mysql> select * from dep1;
+-----+-----------+-------------------------------------
| id | dep_name | dep_desc
+-----+-----------+-------------------------------------
| 3 | 銷售部 | 負責產品的銷售和后期的客戶關系維護
| 4 | 咨詢部 | 公司產品介紹
| 200 | 技術部 | 技術支持
+-----+-----------+-------------------------------------
3 rows in set (0.00 sec)

mysql> select * from emp1;
+----+----------+------------+--------+
| id | emp_name | emp_gender | dep_id |
+----+----------+------------+--------+
| 1 | 張三 | male | 200 |
| 3 | 王五 | male | 3 |
| 4 | 小紅 | male | 4 |
| 5 | 小麗 | male | 4 |
+----+----------+------------+--------+
4 rows in set (0.00 sec)

'''

多對多

# 圖書表與作者表之間的關系
"""
仍然站在兩張表的角度:
1.站在圖書表:一本書可不可以有多個作者,可以!那就是書多對一作者
2.站在作者表:一個作者可不可以寫多本書,可以!那就是作者多對一書
雙方都能一條數據對應對方多條記錄,這種關系就是多對多!
"""
# 先來想如何創建表?圖書表需要有一個外鍵關聯作者,作者也需要有一個外鍵字段關聯圖書。問題來了,先創建誰都不合適!如何解決?
# 建立第三張表,該表中有一個字段fk左表的id,還有一個字段是fk右表的id
多對多關系的建立 必須手動創建第三張表 用來專門記錄兩種表之間的關系


先建兩種普通的表 不需要設置外鍵
create table book(
id int primary key auto_increment,
b_name varchar(16),
prince double(255,30)
);

create table author(
id int primary key auto_increment,
name varchar(16),
age tinyint unsigned,
gender enum('male','female','others') default 'female'
);

create table authorbook(
id int primary key auto_increment,
author_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade,
book_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade
);

insert into author(name,age) values('A',12),('B',13),('C',14),('D',289);
#查看作者信息

mysql> select * from author;
+----+------+------+--------+
| id | name | age | gender |
+----+------+------+--------+
| 1 | A | 12 | female |
| 2 | B | 13 | female |
| 3 | C | 14 | female |
| 4 | D | 255 | female |
+----+------+------+--------+


insert into book(b_name,prince) values('家',28.99),('風箏',36.99),
('偷影子的人',32.99),('菊與刀',18.888888888);

#查看書籍信息
mysql> select * from book;
+----+-----------------+-----------------------------------+
| id | b_name | prince |
+----+-----------------+-----------------------------------+
| 1 | 家 | 28.990000000000000000000000000000 |
| 2 | 風箏 | 36.990000000000000000000000000000 |
| 3 | 偷影子的人 | 32.990000000000000000000000000000 |
| 4 | 菊與刀 | 18.888888888000000000000000000000 |
+----+-----------------+-----------------------------------+

insert into authorbook(author_id,book_id) values(1,4),(1,2),(2,3),(1,3),
(3,2),(2,1),(3,1),(4,1);

#查看作者與書籍一一對應關系表
mysql> select * from authorbook;
+----+-----------+---------+
| id | author_id | book_id |
+----+-----------+---------+
| 9 | 1 | 4 |
| 10 | 1 | 2 |
| 11 | 2 | 3 |
| 12 | 1 | 3 |
| 13 | 3 | 2 |
| 14 | 2 | 1 |
| 15 | 3 | 1 |
| 16 | 4 | 1 |
+----+-----------+---------+


#改 作者(author)字段id
update author set id=200 where id=2;

mysql> update author set id=200 where id=2;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from author;
+-----+------+------+--------+
| id | name | age | gender |
+-----+------+------+--------+
| 1 | A | 12 | female |
| 3 | C | 14 | female |
| 4 | D | 255 | female |
| 200 | B | 13 | female |
+-----+------+------+--------+

#查看作者與書籍一一對應關系表 z只要是author_id=2的字段都被改成author_id=200
mysql> select * from authorbook;
+----+-----------+---------+
| id | author_id | book_id |
+----+-----------+---------+
| 9 | 1 | 4 |
| 10 | 1 | 2 |
| 11 | 200 | 3 |
| 12 | 1 | 3 |
| 13 | 3 | 2 |
| 14 | 200 | 1 |
| 15 | 3 | 1 |
| 16 | 4 | 1 |
+----+-----------+---------+


#改 書籍(book)字段id
update book set id=238 where id=3

mysql> update book set id=238 where id=3;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from book;
+-----+-----------------+-----------------------------------+
| id | b_name | prince |
+-----+-----------------+-----------------------------------+
| 1 | 家 | 28.990000000000000000000000000000 |
| 2 | 風箏 | 36.990000000000000000000000000000 |
| 4 | 菊與刀 | 18.888888888000000000000000000000 |
| 238 | 偷影子的人 | 32.990000000000000000000000000000 |
+-----+-----------------+-----------------------------------+

mysql> select * from book;
+-----+-----------------+-----------------------------------+
| id | b_name | prince |
+-----+-----------------+-----------------------------------+
| 1 | 家 | 28.990000000000000000000000000000 |
| 2 | 風箏 | 36.990000000000000000000000000000 |
| 4 | 菊與刀 | 18.888888888000000000000000000000 |
| 238 | 偷影子的人 | 32.990000000000000000000000000000 |
+-----+-----------------+-----------------------------------+
4 rows in set (0.00 sec)

mysql> select * from authorbook;
+----+-----------+---------+
| id | author_id | book_id |
+----+-----------+---------+
| 9 | 1 | 4 |
| 10 | 1 | 2 |
| 11 | 200 | 238 |
| 12 | 1 | 238 |
| 13 | 3 | 2 |
| 14 | 200 | 1 |
| 15 | 3 | 1 |
| 16 | 4 | 1 |
+----+-----------+---------+


#刪除字段author_id=200

mysql> delete from author where id=200;
Query OK, 1 row affected (0.06 sec)

mysql> select * from authorbook;
+----+-----------+---------+
| id | author_id | book_id |
+----+-----------+---------+
| 9 | 1 | 4 |
| 10 | 1 | 2 |
| 12 | 1 | 238 |
| 13 | 3 | 2 |
| 15 | 3 | 1 |
| 16 | 4 | 1 |
+----+-----------+---------+


#刪除字段bookid=238
mysql> delete from book where id=238;
Query OK, 1 row affected (0.06 sec)

mysql> select * from authorbook;
+----+-----------+---------+
| id | author_id | book_id |
+----+-----------+---------+
| 9 | 1 | 4 |
| 10 | 1 | 2 |
| 13 | 3 | 2 |
| 15 | 3 | 1 |
| 16 | 4 | 1 |
+----+-----------+---------+

還可以這樣刪除=====>
mysql> delete from authorbook where id=9;
Query OK, 0 rows affected (0.00 sec)
+----+-----------+---------+
| id | author_id | book_id |
+----+-----------+---------+
| 10 | 1 | 2 |
| 13 | 3 | 2 |
| 15 | 3 | 1 |
| 16 | 4 | 1 |
+----+-----------+---------+

然后查看 mysql> select * from book; mysql> select * from author;

 

一對一
一對一表關系
1.一對一的場景 當你的表特別龐大的時候 你可以考慮拆分表
2.聯想老男孩的客戶和學生

create table userdetail(
id int primary key auto_increment,
addr varchar(128) unique,
phone int not null,
qq varchar(11) not null);

create table user(
id int primary key auto_increment,
name varchar(16) not null,
age int ,
userdetail_id int unique,
foreign key(userdetail_id) references userdetail(id)
on update cascade
on delete cascade
);

insert into userdetail(addr,phone,qq) values('安徽',13568462190,'1148596457'),('河南',18891452563,'1854894445'),('山東',17750504669,'1132101165');

insert into user(name,age,userdetail_id) values('zhang',19,1),('li',23,2),('huang',22,3);

 


免責聲明!

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



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