MySQL聯(lián)結(jié)表介紹以及使用詳解
MySQL的前情介紹
??大家好呀,今天是我第N次寫(xiě)MySQL,也是最近才學(xué)習(xí)MySQL,也想著記錄一下自己的學(xué)習(xí)過(guò)程,并且分享給大家尼!
本章詳情
??本章將介紹什么是聯(lián)結(jié),為什么要使用聯(lián)結(jié),如何編寫(xiě)使用聯(lián)結(jié)的SELECT語(yǔ)句。
聯(lián)結(jié)
前言
SQL最強(qiáng)大的功能之一就是能在數(shù)據(jù)檢索查詢(xún)的執(zhí)行中聯(lián)結(jié) (join)表。聯(lián)結(jié)是利用SQL的SELECT能執(zhí)行的最重要的操作,很好地理解聯(lián)結(jié)及其語(yǔ)法是學(xué)習(xí)SQL的一個(gè)極為重要的組成部分。
在能夠有效地使用聯(lián)結(jié)前,必須了解關(guān)系表以及關(guān)系數(shù)據(jù)庫(kù)設(shè)計(jì)的些基礎(chǔ)知識(shí)。下面的介紹并不是這個(gè)內(nèi)容的全部知識(shí),但作為入門(mén)已經(jīng)足夠了。
關(guān)系表
??理解關(guān)系表的最好方法是來(lái)看一個(gè)現(xiàn)實(shí)世界中的例子:
現(xiàn)在,假如有由同一供應(yīng)商生產(chǎn)的多種物品,那么在何處存儲(chǔ)供應(yīng)商信息(如,供應(yīng)商名、地址、聯(lián)系方法等)呢?將這些數(shù)據(jù)與產(chǎn)品信息分開(kāi)存儲(chǔ)的理由如下。
- 因?yàn)橥还?yīng)商生產(chǎn)的每個(gè)產(chǎn)品的供應(yīng)商信息都是相同的,對(duì)每個(gè)產(chǎn)品重復(fù)此信息既浪費(fèi)時(shí)間又浪費(fèi)存儲(chǔ)空間。
- 如果供應(yīng)商信息改變(例如,供應(yīng)商搬家或電話(huà)號(hào)碼變動(dòng)),只需改動(dòng)一次即可。
- 如果有重復(fù)數(shù)據(jù)(即每種產(chǎn)品都存儲(chǔ)供應(yīng)商信息),很難保證每次輸入該數(shù)據(jù)的方式都相同。不一致的數(shù)據(jù)在報(bào)表中很難利用。
關(guān)鍵
關(guān)鍵是,相同數(shù)據(jù)出現(xiàn)多次決不是一件好事,此因素是關(guān)系數(shù)據(jù)庫(kù)設(shè)計(jì)的基礎(chǔ)。關(guān)系表的設(shè)計(jì)就是要保證把信息分解成多個(gè)表,一類(lèi)數(shù)據(jù)一個(gè)表。各表通過(guò)某些常用的值(即關(guān)系設(shè)計(jì)中的關(guān)系 (relational))互相關(guān)聯(lián)。
分析
??在這個(gè)例子中,可建立兩個(gè)表,一個(gè)存儲(chǔ)供應(yīng)商信息,另一個(gè)存儲(chǔ)產(chǎn)品信息。vendors表包含所有供應(yīng)商信息,每個(gè)供應(yīng)商占一行,每個(gè)供應(yīng)商具有唯一的標(biāo)識(shí)。此識(shí)稱(chēng)為主鍵 (primary key) (在第首篇文章中首次提到),可以是供應(yīng)商ID或任何其他唯一值。
products表只存儲(chǔ)產(chǎn)品信息,它除了存儲(chǔ)供應(yīng)商ID (vendors表的主鍵)外不存儲(chǔ)其他供應(yīng)商信息。vendors表的主鍵又叫作products的外鍵,它將vendors表與products表關(guān)聯(lián),利用供應(yīng)商ID能從vendors表中找出相應(yīng)供應(yīng)商的詳細(xì)信息。
外鍵(foreign key)
外鍵為某個(gè)表中的一列,它包含另一個(gè)表的主鍵值,定義了兩個(gè)表之間的關(guān)系。
好處
- 供應(yīng)商信息不重復(fù),從而不浪費(fèi)時(shí)間和空間;
- 如果供應(yīng)商信息變動(dòng),可以只更新vendors表中的單個(gè)記錄,相關(guān)表中的數(shù)據(jù)不用改動(dòng);
- 由于數(shù)據(jù)無(wú)重復(fù),顯然數(shù)據(jù)是一致的,這使得處理數(shù)據(jù)更簡(jiǎn)單。
??總之,關(guān)系數(shù)據(jù)可以有效地存儲(chǔ)和方便地處理。因此,關(guān)系數(shù)據(jù)庫(kù)的可伸縮性遠(yuǎn)比非關(guān)系數(shù)據(jù)庫(kù)要好。
可伸縮性(scale)
能夠適應(yīng)不斷增加的工作量而不失敗。設(shè)計(jì)良好的數(shù)據(jù)庫(kù)或應(yīng)用程序稱(chēng)之為可伸縮性好 (scale well)
為什么要使用聯(lián)結(jié)
正如所述,分解數(shù)據(jù)為多個(gè)表能更有效地存儲(chǔ),更方便地處理,并且具有更大的可伸縮性。但這些好處是有代價(jià)的。
??如果數(shù)據(jù)存儲(chǔ)在多個(gè)表中,怎樣用單條SELECT語(yǔ)句檢索出數(shù)據(jù)?
答案是使用聯(lián)結(jié)。簡(jiǎn)單地說(shuō),聯(lián)結(jié)是一種機(jī)制,用來(lái)在一條SELECT語(yǔ)句中關(guān)聯(lián)表,因此稱(chēng)之為聯(lián)結(jié)。使用特殊的語(yǔ)法,可以聯(lián)結(jié)多個(gè)表返回一組輸出,聯(lián)結(jié)在運(yùn)行時(shí)關(guān)聯(lián)表中正確的行。
維護(hù)引用完整性
維護(hù)引用完整性重要 的是,要理解聯(lián)結(jié)不是物理實(shí)體。換句話(huà)說(shuō),它在實(shí)際的數(shù)據(jù)庫(kù)表中不存在。聯(lián)結(jié)由MySQL根據(jù)需要建立,它存在于查詢(xún)的執(zhí)行當(dāng)中。
在使用關(guān)系表時(shí),僅在關(guān)系列中插入合法的數(shù)據(jù)非常重要?;氐竭@里的例子,如果在products表中插入擁有非法供應(yīng)商ID即沒(méi)有在vendors表中出現(xiàn))的供應(yīng)商生產(chǎn)的產(chǎn)品,則這些產(chǎn)品是不可訪問(wèn)的,因?yàn)樗鼈儧](méi)有關(guān)聯(lián)到某個(gè)供應(yīng)商。為防止這種情況發(fā)生,可指示MySQL只允許在products表的供應(yīng)商ID列中出現(xiàn)合法值(即出現(xiàn)在vendors表中的供應(yīng)商)這就是維護(hù)引用完整性,它是通過(guò)在表的定義中指定主鍵和外鍵來(lái)實(shí)現(xiàn)的。(這將在后面的文章種介紹)。
創(chuàng)建聯(lián)結(jié)
聯(lián)結(jié)的創(chuàng)建非常簡(jiǎn)單,規(guī)定要聯(lián)結(jié)的所有表以及它們?nèi)绾侮P(guān)聯(lián)即可。請(qǐng)看下面的例子:
輸入
SELECT vend_name,prod_name,prod_price FROM vendors,products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name,prod_name;
輸出
分析
我們來(lái)考察一下此代碼。SELECT語(yǔ)與前面所有語(yǔ)一樣指定要檢索的列。這里,最大的差別是所指定的兩個(gè)列(prod_name和prod_price)在一個(gè)表中,而另一個(gè)列(vend_name)在另一個(gè)表中。
現(xiàn)在來(lái)看FROM子句。與以前的SELECT語(yǔ)句不一樣,這條語(yǔ)句的FROM子句列出了兩個(gè)表,分別是vendors和products。它們就是這條SELECT語(yǔ)句聯(lián)結(jié)的兩個(gè)表的名字。這兩個(gè)表用WHERE子句正確聯(lián)結(jié),WHERE子句指示MySQL匹配vendors表中的vend_id和products表中的vend_id。
可以看到要匹配的兩個(gè)列以vendors.vend id和products.vend_id指定。這里需要這種完全限定列名,因?yàn)槿绻唤o出vend_id則MySQL不知道指的是哪一個(gè) (它們有兩個(gè),每個(gè)表中一個(gè))。
完全限定列名
在引用的列可能出現(xiàn)二義性時(shí),必須使用完全限定列名(用一個(gè)點(diǎn)分隔的表名和列名)。如果引用一個(gè)沒(méi)有用表名限制的具有二義性的列名,MySOL將返回錯(cuò)誤。
WHERE子句的重要性
提示
利用WHERE子句建立聯(lián)結(jié)關(guān)系似乎有點(diǎn)奇怪,但實(shí)際上,有一個(gè)很充分的理由。請(qǐng)記住,在一條SELECT語(yǔ)句中聯(lián)結(jié)幾個(gè)表時(shí),相應(yīng)的關(guān)系是在運(yùn)行中構(gòu)造的。在數(shù)據(jù)庫(kù)表的定義中不存在能指示MySQL如何對(duì)表進(jìn)行聯(lián)結(jié)的東西。你必須自已做這件事情。在聯(lián)結(jié)兩個(gè)表時(shí),你實(shí)際上做的是將第一個(gè)表中的每一行與第二個(gè)表中的每一行配對(duì)。WHERE子句作為過(guò)濾條件,它只包含那些匹配給定條件(這里是聯(lián)結(jié)條件)的行。沒(méi)有WHERE子句,第一個(gè)表中的每個(gè)行將與第二個(gè)表中的每個(gè)行配對(duì),而不管它們邏輯上是否可以配在一起。
笛卡爾積(cartesian product)
由沒(méi)有聯(lián)結(jié)條件的表關(guān)系返回的結(jié)果為笛卡兒積。檢索出的行的數(shù)目將是第一個(gè)表中的行數(shù)乘以第二個(gè)表中的行數(shù)。
為了理解這一點(diǎn),請(qǐng)看下面的SELECT語(yǔ)句及其輸出
輸入
SELECT vend_name,prod_name,prod_price FROM vendors,products ORDER BY vend_name,prod_name;
輸出
分析
從上面的輸出中可以看到,相應(yīng)的笛卡兒積不是我們所想要的。這里返回的數(shù)據(jù)用每個(gè)供應(yīng)商匹配了每個(gè)產(chǎn)品,它包括了供應(yīng)商不正確的產(chǎn)品。實(shí)際上有的供應(yīng)商根本就沒(méi)有產(chǎn)品。
不要忘記WHERE子句
應(yīng)該保證所有聯(lián)結(jié)都有WHERE子,否則MySQL將返回比想要的數(shù)據(jù)多得多的數(shù)據(jù)。同理,應(yīng)該保證WHERE子句的正確性。不正確的過(guò)濾條件將導(dǎo)致MySQL返回不正確的數(shù)據(jù).
叉聯(lián)結(jié)
有時(shí)我們會(huì)聽(tīng)到返回稱(chēng)為叉聯(lián)結(jié)(cross join)的笛卡兒積的聯(lián)結(jié)類(lèi)型。
內(nèi)部聯(lián)結(jié)
目前為止所用的聯(lián)結(jié)稱(chēng)為等值聯(lián)結(jié) (equijoin),它基于兩個(gè)表之間的相等測(cè)試。這種聯(lián)結(jié)也稱(chēng)為內(nèi)部聯(lián)結(jié)。其實(shí),對(duì)于這種聯(lián)結(jié)可以使用稍微不同的語(yǔ)法來(lái)明確指定聯(lián)結(jié)的類(lèi)型。下面的SELECT語(yǔ)句返回與前面例子完全相同的數(shù)據(jù):
輸入
SELECT vend_name,prod_name,prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id;
分析
??此語(yǔ)句中的SELECT與前面的SELECT語(yǔ)句相同,但FROM子句不同。這里,兩個(gè)表之間的關(guān)系是FROM子句的組成部分,以INNER JOIN指定。在使用這種語(yǔ)法時(shí),聯(lián)結(jié)條件用特定的ON子句而不是WHERE子句給出。傳遞給ON的實(shí)際條件與傳遞給WHERE的相同。
使用哪種語(yǔ)法
ANSI SQL規(guī)范首選INNER JOIN語(yǔ)法。此外盡管使用WHERE子句定義聯(lián)結(jié)的確比較簡(jiǎn)單,但是使用明確的聯(lián)結(jié)語(yǔ)法能夠確保不會(huì)忘記聯(lián)結(jié)條件,有時(shí)候這樣做也能影響性能。
聯(lián)結(jié)多個(gè)表
?SQL對(duì)一條SELECT語(yǔ)句中可以聯(lián)結(jié)的表的數(shù)目沒(méi)有限制。創(chuàng)建聯(lián)結(jié)的基本規(guī)則也相同。首先列出所有表,然后定義表之間的關(guān)系。例如:
輸入
SELECT prod_name,vend_name,prod_price,quantity FROM orderitems, products,vendors WHERE products.vend_id = vendors.vend_id AND orderitems.prod_id = products.prod_id AND order_num = 20005;
輸出
分析
?此例子顯示編號(hào)為20005的訂單中的物品。訂單物品存儲(chǔ)在orderitems表中。每個(gè)產(chǎn)品按其產(chǎn)品ID存儲(chǔ),它引用products表中的產(chǎn)品。這些產(chǎn)品通過(guò)供應(yīng)商ID聯(lián)結(jié)到vendors表中相應(yīng)的供應(yīng)商,供應(yīng)商ID存儲(chǔ)在每個(gè)產(chǎn)品的記錄中。這里的FROM子句列出了3個(gè)表,而WHERE子句定義了這兩個(gè)聯(lián)結(jié)條件,而第三個(gè)聯(lián)結(jié)條件用來(lái)過(guò)濾出訂單20005中的物品。
如何鞏固學(xué)習(xí)
提示:在學(xué)習(xí)的過(guò)程中,我們需要先自行進(jìn)行思考,而不是一遇到不會(huì)的就放棄思考直接看答案,如果最后遇到真的不會(huì)的題目,我們可以適當(dāng)?shù)倪M(jìn)行觀看答案,看自己的思路是否正確,在作出正確的判斷
本文小結(jié)
聯(lián)結(jié)是SQL中最重要最強(qiáng)大的特性,有效地使用聯(lián)結(jié)需要對(duì)關(guān)系數(shù)據(jù)庫(kù)設(shè)計(jì)有基本的了解。本章隨著對(duì)聯(lián)結(jié)的介紹講述了關(guān)系數(shù)據(jù)庫(kù)設(shè)計(jì)的一些基本知識(shí),包括等值聯(lián)結(jié)(也稱(chēng)為內(nèi)部聯(lián)結(jié)) 這種最經(jīng)常使用的聯(lián)結(jié)形式。下一篇文章將介紹如何創(chuàng)建其他類(lèi)型的聯(lián)結(jié)
總結(jié)
到此這篇關(guān)于MySQL聯(lián)結(jié)表介紹以及使用的文章就介紹到這了,更多相關(guān)MySQL聯(lián)結(jié)表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL入門(mén)(四) 數(shù)據(jù)表的數(shù)據(jù)插入、更新、刪除
這篇文章主要介紹了mysql數(shù)據(jù)庫(kù)中表的插入、更新、刪除非常簡(jiǎn)單,但是簡(jiǎn)單的也要學(xué)習(xí),細(xì)節(jié)決定成敗,需要的朋友可以參考下2018-07-07mysql的innodb和myisam的區(qū)別及說(shuō)明
這篇文章主要介紹了mysql的innodb和myisam的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03通過(guò)mysqladmin遠(yuǎn)程管理mysql的方法
在一些特殊場(chǎng)景下,想要遠(yuǎn)程重啟mysql,以便讓某些修改能及時(shí)的生效,但是mysql并沒(méi)有提供遠(yuǎn)程重啟的功能,唯一能做的就是遠(yuǎn)程關(guān)閉mysql服務(wù)2013-03-03保存圖片到MySQL以及從MySQL讀取圖片全過(guò)程
有人喜歡使用mysql來(lái)存儲(chǔ)圖片,而有的人喜歡把圖片存儲(chǔ)在文件系統(tǒng)中,而當(dāng)我們要處理成千上萬(wàn)的圖片時(shí),會(huì)引起技術(shù)問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于如何保存圖片到MySQL以及從MySQL讀取圖片的相關(guān)資料,需要的朋友可以參考下2023-05-05SQL insert into語(yǔ)句寫(xiě)法講解
這篇文章主要介紹了SQL insert into語(yǔ)句寫(xiě)法講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08在MySQL中按字符串中的數(shù)字排序的詳細(xì)教程
本文將詳細(xì)介紹如何在MySQL中利用正則表達(dá)式提取字符串中的數(shù)字并按這些數(shù)字進(jìn)行排序,以一個(gè)具體的例子來(lái)說(shuō)明,使得即使是數(shù)據(jù)庫(kù)操作的初學(xué)者也能輕松理解和應(yīng)用,需要的朋友可以參考下2024-07-07Mysql主鍵和唯一鍵的區(qū)別點(diǎn)總結(jié)
在本篇文章中小編給大家分享了關(guān)于Mysql主鍵和唯一鍵的區(qū)別,有興趣的朋友們學(xué)習(xí)下吧。2019-02-02MySQL數(shù)據(jù)庫(kù)如何給表設(shè)置約束詳解
約束主要完成對(duì)數(shù)據(jù)的檢驗(yàn),保證數(shù)據(jù)庫(kù)數(shù)據(jù)的完整性;如果有相互依賴(lài)數(shù)據(jù),保證該數(shù)據(jù)不被刪除,本篇文章教你如何給表設(shè)置約束2022-03-03