MySQL詳細(xì)講解多表關(guān)聯(lián)查詢
數(shù)據(jù)庫設(shè)計(jì)范式
目前數(shù)據(jù)庫設(shè)計(jì)有五種范式 , 一般我們數(shù)據(jù)庫只需要滿足前三項(xiàng)即可
第一范式 : 確保每列保持原子性
什么是原子性? 意思就是不可再分的,例如下

聯(lián)系方式有 QQ,微信 , 電話等等 , 顯然此列不滿足原子性, 如果是單獨(dú)的QQ或者電話等,則只有一個, 滿足第一范式
第二范式 : 要有主鍵,要求其他字段都依賴于主鍵
為什么主鍵這么重要? 我們可以這樣理解, 如果把表當(dāng)作一個隊(duì)伍, 那么主鍵就是這個隊(duì)伍的隊(duì)旗
• 沒有主鍵就沒有唯一性,沒有唯一性在集合中就定位不到這行記錄,所以要主鍵。
• 其他字段為什么要依賴于主鍵?因?yàn)椴灰蕾囉谥麈I,就找不到他們。更重要的是,其他字段組成的這行記錄和主鍵表示的是同一個東西,而主鍵是唯一的,它們只需要依賴于主鍵,也就成了唯一的。
第三范式 : 第三范式就是要消除傳遞依賴,方便理解,可以看做是“消除冗余”
這個要怎樣理解呢? 看下述例子

如果我們一張表設(shè)計(jì)成上面這樣, 大致看很正常, 但我們把這張表拆分開來

如果這樣做的話, 是不是條理清晰了很多, 我們直接通過商品編號來關(guān)聯(lián)這兩張表, 無論在哪方面,都比全部擠在一張表要優(yōu)于很多
外鍵
我們知道有主鍵 , 主鍵相當(dāng)于表的標(biāo)識, 那么外鍵呢 ?
● 外鍵:引用另外一個數(shù)據(jù)表的某條記錄。
● 外鍵列類型與主鍵列類型保持一致 ,數(shù)據(jù)表之間的關(guān)聯(lián)/ 引用關(guān)系是依靠具體的主鍵( primary key )和外鍵(foreign key)建立起來的
語法:
添加外鍵約束
ALTER TABLE 表名 ADD [CONSTRAINT 約束名 ] FOREIGN KEY( 外鍵列 )
REFERENCES 關(guān)聯(lián)表( 主鍵 );
刪除外檢鍵 ALTER TABLE 表名 DROP FOREIGN KEY 外鍵約束名
我們在上面第三范式的例子中說到, 消除冗余, 通過某一列來關(guān)聯(lián)兩個表 , 那么這一個連接起兩個表的列我們一般就會設(shè)置為外鍵
但是, 如果我們需要兩個表關(guān)聯(lián)查詢, 也是不一定去使用外鍵約束的
- 如果兩張表關(guān)聯(lián)查詢 , 我們并沒有去添加外鍵約束, 我們把這種稱為弱引用
- 如果添加了外鍵約束,那么它就是強(qiáng)引用
那么這兩種引用區(qū)別在哪呢?
我們知道 , 當(dāng)我們使用外鍵后 , 外鍵所在的是從表 , 外鍵指向主表的主鍵 , 那么此時就在這兩張表之間建立起了約束 , 這時我們就不能隨意的去修改主表或者從表里關(guān)聯(lián)的值 , 這就是強(qiáng)引用
1、當(dāng)主表中沒有對應(yīng)的記錄時,不能將記錄添加到從表
2、不能更改主表中的值而導(dǎo)致從表中的記錄孤立
3、從表存在與主表對應(yīng)的記錄,不能從主表中刪除該行
4、刪除主表前,先刪從表
弱引用我們則可以隨意修改關(guān)聯(lián)之間的值
-- 創(chuàng)建學(xué)生表
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT,
num INT,
NAME VARCHAR(20),
sex CHAR(1),
gradeId INT -- 從表外鍵列
)
-- 創(chuàng)建年級表
CREATE TABLE grade(
-- 主表主鍵列
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
)
-- 添加外鍵約束
ALTER TABLE student ADD CONSTRAINT fk_grade
FOREIGN KEY(gradeId) REFERENCES grade(id)主表創(chuàng)建并添加數(shù)據(jù) :

從表創(chuàng)建并添加數(shù)據(jù) :

可以看到 , gradeId字段添加了外鍵約束
這時我們試著去刪除主表的一列 :

可以看到 , 是不能去隨意改變主表的, 如果一旦改變,就會使得從表中的數(shù)據(jù)孤立
內(nèi)連接

● 把滿足了條件的兩張表中的交集數(shù)據(jù)查詢出來
語法:
Select 結(jié)果 from 表 1 ,表 2 where 表 1.column1 = 表 2.column2
內(nèi)連接有等值連接, 非等值連接, 自連接, 這里我們主要討論自連接
笛卡爾乘積現(xiàn)象:表1有m行,表2有n行,結(jié)果=m*n
什么是自連接呢 , 就是自己關(guān)聯(lián)自己 , 自己和自己做笛卡爾積, 這么說可能不好理解, 舉例說明如下:
我們平時在淘寶網(wǎng)購填地址的時候, 都是采用選擇的方式, 先選擇省,然后是省下面的市, 接著是市下面的區(qū)(縣) ,它們都是在數(shù)據(jù)庫中存著, 如何去實(shí)現(xiàn)這個功能呢 ?
有人可能會說, 建三張表相互關(guān)聯(lián)即可 , 但實(shí)際是 , 我們采用自連接的方式 , 一張表即可實(shí)現(xiàn)
CREATE TABLE demo( -- 建立demo表
id INT PRIMARY KEY,
NAME VARCHAR(50),
pid INT
)往表中填入數(shù)據(jù), pid為關(guān)聯(lián)上一級的id

-- 自連接
-- 在多表關(guān)系中我們需要定義別名來區(qū)分
SELECT d1.name,d2.name,d3.name FROM demo d1
INNER JOIN demo d2 ON d1.id=d2.pid --自連接條件
INNER JOIN demo d3 ON d2.id=d3.pid --自連接條件
WHERE d3.id=6101011 -- 查詢條件結(jié)果 :

外連接
外連接又分為左外連接與右外連接
先看左外連接 :

語法
select 結(jié)果 from 表1 left join 表 2 on 表1.column1 = 表 2.column2
左連接和內(nèi)連接有什么不同呢? 通過兩幅圖我們就可以看出 ,內(nèi)連接是取了兩張表的共同部分 , 而左連接是取了左邊表的全部(包括兩張表的共同部分)
也就是說, 不僅查詢兩張表的共同部分, 并且左邊表會被全部查詢出來
我們通過上面外鍵所建的表來演示 , 為了演示方便,我們?yōu)閟tudent表再添加一列數(shù)據(jù)

可以看到, 此時第五列并沒有去關(guān)聯(lián)grade表
-- 左外連接查詢
SELECT * FROM student s
LEFT JOIN grade g ON s.gradeId= g.id查詢結(jié)果如下 :

那么說到這, 右外連接也就不難理解了 , 每次都會完整的查詢右邊的表

同樣我們再為grade添加一條無關(guān)聯(lián)的數(shù)據(jù)

語法 :
select 結(jié)果 from 表1 right join 表2 on 表1.column1 = 表2.column2
-- 右外連接查詢
SELECT * FROM student s
RIGHT JOIN grade g ON s.gradeId= g.id查詢結(jié)果 :

可以看到, 右表被完全查詢
結(jié)語
mysql是一款優(yōu)秀的關(guān)系型數(shù)據(jù)庫 , 在多表查詢中,通過表與表之間的關(guān)系, 我們就可以連接起各種數(shù)據(jù) , 通過外鍵約束等,我們可以在表與表之間建立起聯(lián)系 , 等等
到此這篇關(guān)于MySQL詳細(xì)講解多表關(guān)聯(lián)查詢的文章就介紹到這了,更多相關(guān)MySQL多表關(guān)聯(lián)查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL防止delete命令刪除數(shù)據(jù)的兩種方法
在sql中刪除數(shù)據(jù)庫中記錄我們會使用到delete命令,這樣如果不小心給刪除了很難恢復(fù)了,下面我來總結(jié)一些刪除數(shù)據(jù)但是不在數(shù)據(jù)庫刪除的方法,有需要的朋友可以參考一下2013-08-08
MySQL數(shù)據(jù)庫表內(nèi)容的增刪查改操作實(shí)例詳解
對于刪除操作來說,是將表單個或者多個數(shù)據(jù)進(jìn)行刪除,而截?cái)鄤t是對整個表進(jìn)行操作,會將整個表數(shù)據(jù)都清除,本文給大家介紹MySQL數(shù)據(jù)庫表內(nèi)容的增刪查改操作大全,感興趣的朋友一起看看吧2025-04-04
安裝MySQL后include目錄下沒有找到libmysql.lib
安裝了MySQL后,在其安裝目錄下的include文件夾并沒有找到libmysql.lib,主要原因是在安裝MySQL的時候,沒有勾選develop component這一選項(xiàng)造成的2014-08-08
如何解決MySQL5升級為MySQL8遇到的問題my.ini
這篇文章主要介紹了如何解決MySQL5升級為MySQL8遇到的問題my.ini,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
圖文詳解Mysql使用left?join寫查詢語句執(zhí)行很慢問題的解決
最近工作中遇到一個非常奇怪的問題,mysql中有兩張表,test_info和test_do_info需要進(jìn)行LEFT?JOIN關(guān)聯(lián)查詢,下面這篇文章主要給大家介紹了關(guān)于Mysql使用left?join寫查詢語句執(zhí)行很慢問題的解決方法2023-04-04
MySQL解決數(shù)據(jù)導(dǎo)入導(dǎo)出含有外鍵的方案
這篇文章主要介紹了MySQL解決數(shù)據(jù)導(dǎo)入導(dǎo)出含有外鍵的情況,文中通過圖文結(jié)合的方式給大家講解的非常詳細(xì),對大家解決問題有一定的幫助,需要的朋友可以參考下2024-11-11
淺談sql連接查詢的區(qū)別 inner,left,right,full
下面小編就為大家?guī)硪黄獪\談sql連接查詢的區(qū)別 inner,left,right,full。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10
MySQL8.0窗口函數(shù)入門實(shí)踐及總結(jié)
這篇文章主要給大家介紹了關(guān)于MySQL8.0窗口函數(shù)入門實(shí)踐及總結(jié)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用MySQL8.0具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06

