目錄
- 外鍵(Foreign Key)
- 如何確定表關(guān)系
- 如何建立表關(guān)系
- 一對多關(guān)系 - 員工表和部門表
- 多對多
- 一對一
- 表關(guān)系總結(jié)
外鍵(Foreign Key)
按照上述所說,一張表存儲員工信息會極大的浪費資源,重復(fù)數(shù)據(jù)太多,這個問題就類似于將所有的代碼都寫在了一個py文件中,因此我們可以將一個表拆成不同的表,在這不同的表之間建立關(guān)聯(lián),而建立關(guān)聯(lián)就需要使用外鍵foreign key。外鍵也屬于約束條件的一種。
如何確定表關(guān)系
表與表之間的關(guān)系有三種一對多、多對多、一對一。那么如何確定表與表之間的關(guān)系呢?
在確定表與表之間的關(guān)系時建議換位思考,什么意思呢?就是分別站在兩張表的角度去考慮,比如員工表和部門表的關(guān)系:
先站在員工表的角度:員工表中一個員工能否屬于多個部門呢?答案是不能
再站在部門表的角度:部門表中一個部門能否有多個員工呢?答案是可以
因此員工表與部門表是單向的一對多,那么員工表和部門表就是一對多的關(guān)系。
如何建立表關(guān)系
在建立表關(guān)系時,表與表之間的關(guān)聯(lián)通常以主鍵id作為關(guān)聯(lián)字段。
一對多關(guān)系 - 員工表和部門表
在MySQL的關(guān)系在沒有多對一的概念,一對多和多對一都是一對多。在創(chuàng)建一對多表關(guān)系時需要遵循以下幾點:
第一,外鍵字段建立在多的一方,即員工表
第二,在創(chuàng)建表的時候,一定要先創(chuàng)建被關(guān)聯(lián)一方,即部門表
第三,在錄入數(shù)據(jù)的時候也必須先錄入被關(guān)聯(lián)表的數(shù)據(jù),即部門表的數(shù)據(jù)
第四,當(dāng)不同的表建立關(guān)系時,需要進行級聯(lián)更新和刪除也可以稱為同步更新同步刪除,如果不建立級聯(lián)更新和刪除的話,無法對被關(guān)聯(lián)表中被關(guān)聯(lián)的數(shù)據(jù)進行刪除或者修改id的操作,因為兩張表是相互關(guān)聯(lián)的。
-- 創(chuàng)建被關(guān)聯(lián)表,部門表
mysql> create table bm(
id int primary key auto_increment,
bm_name varchar(10),
bm_desc char(64)
);
Query OK, 0 rows affected (0.01 sec)
mysql> desc bm;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| bm_name | varchar(10) | YES | | NULL | |
| bm_desc | char(64) | YES | | NULL | |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
-- 創(chuàng)建外鍵所在的表,員工表
mysql> create table yg(
id int primary key auto_increment,
yg_name varchar(6),
bm_id int,
foreign key(bm_id) references bm(id) -- 表示bm_id是外鍵字段,關(guān)聯(lián)到bm表中的id字段
on update cascade # 級聯(lián)更新
on delete cascade # 級聯(lián)刪除
);
Query OK, 0 rows affected (0.10 sec)
mysql> desc yg;
+---------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| yg_name | varchar(6) | YES | | NULL | |
| bm_id | int(11) | YES | MUL | NULL | |
+---------+------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
-- 插入數(shù)據(jù)
mysql> insert into bm (bm_name, bm_desc) values ('python', '人生苦短'),('go', 'let us go');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from bm;
+----+---------+--------------+
| id | bm_name | bm_desc |
+----+---------+--------------+
| 1 | python | 人生苦短 |
| 2 | go | let us go |
+----+---------+--------------+
2 rows in set (0.00 sec)
mysql> insert into yg (yg_name, bm_id) values ('xu', 1), ('zhuang', 2), ('lili', 1);
Query OK, 3 rows affected (0.09 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from yg;
+----+---------+-------+
| id | yg_name | bm_id |
+----+---------+-------+
| 2 | xu | 1 |
| 3 | zhuang | 2 |
| 4 | lili | 1 |
+----+---------+-------+
3 rows in set (0.00 sec)
-- 外鍵關(guān)聯(lián)的數(shù)據(jù)必須在被關(guān)聯(lián)表中存在否則會報錯哦~
mysql> insert into yg (yg_name, bm_id) values ('xu', 3);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))
-- 如果不使用級聯(lián)更新和刪除的話會出現(xiàn)下面的錯誤,下述的SQL語句后面的文章都會介紹。。。
mysql> update bm set id=5 where id=2; -- 將bm表中id=2的記錄改為id=5
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))
mysql> delete from bm where id =2; -- 刪除bm表中id為2的那條記錄
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))
多對多
多對多的關(guān)系以書籍和作者為例進行詳細(xì)介紹,為什么書籍和作者屬于多對多的關(guān)系呢?
先站在書籍表的角度:一本書是否可以有多個作者?答案是可以
再站在作者表的角度:一個作者是否可以寫多本書?答案是可以
書籍表和作者表是雙向的一對多那么這兩張表的關(guān)系就是多對多。
我們先來創(chuàng)建兩張表:
-- 創(chuàng)建書籍表
create table book(
id int primary key auto_increment,
title varchar(32),
price int,
author_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade
);
-- 創(chuàng)建作者表
create table author(
id int primary key auto_increment,
name varchar(32),
age int,
book_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade
);
如果按照上述方式創(chuàng)建表的話肯定是不可能成功的,在創(chuàng)建一對多的表關(guān)系時我我們說要先創(chuàng)建被關(guān)聯(lián)表,也就是沒有外鍵的表,可是多對多關(guān)系是雙向的一對多,每張表中都會有外鍵的存在,怎么辦呢?解決方案就是創(chuàng)建第三張表,這第三張表用來專門存儲多對多關(guān)系的兩張表的關(guān)聯(lián)。
-- 創(chuàng)建書籍表
mysql> create table book(
id int primary key auto_increment,
name varchar(10),
price int
);
Query OK, 0 rows affected (0.01 sec)
-- 創(chuàng)建作者表
mysql> create table author(
id int primary key auto_increment,
name varchar(6),
age int
);
Query OK, 0 rows affected (0.01 sec)
-- 創(chuàng)建第三章表,存儲book和author表的關(guān)聯(lián)關(guān)系
mysql> create table book2author(
id int primary key auto_increment,
author_id int,
book_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade,
foreign key(book_id) references book(id)
on update cascade
on delete cascade);
Query OK, 0 rows affected (0.02 sec)
一對一
如果一張表的字段特別多,每次查詢數(shù)據(jù)時又不是所有的字段都能用的到,我們就可以將表一一分為二,比如說用戶信息表,用戶的信息包括用戶名 密碼 用戶的年齡 用戶的性別 地址 電話等等,可能經(jīng)常用的只有用戶的用戶名和密碼,這種情況我們就可以將一張用戶信息表拆分成用戶基本信息表和用戶詳細(xì)信息表,同樣判斷這兩張表的關(guān)系還是通過換位思考:
首先看用戶基本信息表:一個用戶能否有多個詳細(xì)信息?答案是不可以;
再看用戶詳情表:一個用戶詳情能否屬于多個用戶?答案是不可以;
單向的一對多都不成立,那么兩者之間的表關(guān)系就是一對一或者沒有關(guān)系。
使用SQL語句建立一對一的外鍵關(guān)系時,外鍵建在任意一方都可以,但是推薦將外鍵建在查詢頻率較高的表中,同樣的,在創(chuàng)建表時還是先創(chuàng)建被關(guān)聯(lián)表。
-- 創(chuàng)建用戶詳情表
create table authordetail(
id int primary key auto_increment,
phone int,
addr varchar(64)
);
-- 用戶基本信息表
create table author(
id int primary key auto_increment,
name varchar(32),
age int,
authordetali_id int,
foreign key(authordetali_id) references authordetali(id)
on update cascade
on delete cascade
);
表關(guān)系總結(jié)
表關(guān)系建立需要使用外鍵foreign key,判斷表與表之間的關(guān)系通過換位思考的方式。
一對多表關(guān)系:外鍵建在多的一方
一對一表關(guān)系:外鍵建在任意一方都可以,推薦建在查詢頻率高的一方
多對多表關(guān)系:需要單獨創(chuàng)建第三張表存儲兩張表的關(guān)聯(lián)關(guān)系
以上就是MySQL 外鍵約束和表關(guān)系相關(guān)總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于MySQL 外鍵約束和表關(guān)系的資料請關(guān)注腳本之家其它相關(guān)文章!
您可能感興趣的文章:- MySQL非空約束(not null)案例講解
- MySQL外鍵約束(FOREIGN KEY)案例講解
- MySQL完整性約束的定義與實例教程
- MySQL 8.0新特性 — 檢查性約束的使用簡介
- MySQL中外鍵的創(chuàng)建、約束以及刪除
- Mysql中索引和約束的示例語句
- MySQL外鍵約束的實例講解
- 詳解MySQL 外鍵約束
- mysql完整性約束實例詳解
- MySQL約束超詳解