自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

第29期:JOIN運(yùn)算剖析

企業(yè)動(dòng)態(tài)
JOIN是SQL中用于多表關(guān)聯(lián)的運(yùn)算,無論從程序員編寫還是數(shù)據(jù)庫實(shí)現(xiàn)角度來看,JOIN都是SQL中最難的運(yùn)算。

【數(shù)據(jù)蔣堂】第29期:JOIN運(yùn)算剖析

JOIN是SQL中用于多表關(guān)聯(lián)的運(yùn)算,無論從程序員編寫還是數(shù)據(jù)庫實(shí)現(xiàn)角度來看,JOIN都是SQL中最難的運(yùn)算。

其實(shí),SQL對(duì)JOIN的定義非常簡單,就是對(duì)兩個(gè)集合(表)做笛卡爾積后再按某種條件過濾,寫出來的語法也就是A JOIN B ON ...的形式。原則上,笛卡爾積后的結(jié)果集應(yīng)當(dāng)是以兩集合成員構(gòu)成的二元組為成員,不過由于SQL中的集合成員總是有字段的記錄,而且也不支持泛型數(shù)據(jù)類型來描述成員為記錄的二元組,所以就簡單地把結(jié)果集處理成由兩表記錄的字段合并后構(gòu)成的新記錄集合。這也是JOIN一詞在英語中的愿意,并沒有乘法(笛卡爾積)的意思。把結(jié)果集理解成二元組還是字段合并的記錄,都不會(huì)影響本文的討論。

JOIN定義中并沒有規(guī)定過濾條件的形式。理論上,只要目標(biāo)結(jié)果集是兩源集笛卡爾積的子集,都可以理解為JOIN運(yùn)算。比如,我們可以計(jì)算 A JOIN B ON A

不過,有經(jīng)驗(yàn)的程序員都知道,現(xiàn)實(shí)中絕大多數(shù)JOIN都是等值JOIN,即過濾條件是一個(gè)或多個(gè)相等關(guān)系(多個(gè)之間是AND關(guān)系),語法形如A JOIN B ON A.ai=B.bi AND ...,其中ai和bi分別是A和B的字段。而前述例子中ON A

根據(jù)對(duì)空值的處理規(guī)則,等值JOIN還可以衍生出LEFT JOIN和FULL JOIN,而且一般會(huì)被分成一對(duì)一、一對(duì)多、多對(duì)多等幾種情況。這些常規(guī)術(shù)語在所有的SQL教科書都有,這里就不再贅述了。

我們來考察下面三種等值JOIN:

1. 外鍵表

表A的某些字段與表B的主鍵關(guān)聯(lián)(所謂關(guān)聯(lián),是指JOIN的過濾條件即由這些對(duì)應(yīng)字段相等構(gòu)成)。A表稱為事實(shí)表,B表稱為維表。A表中與B表主鍵關(guān)聯(lián)的字段稱為A指向B的外鍵,B也稱為A的外鍵表。外鍵表是多對(duì)一的關(guān)系,且只有JOIN和LEFT JOIN,一般不會(huì)用到FULL JOIN。

典型例子:帳戶交易記錄和帳戶基本信息。

2. 同維表

表A的主鍵與表B的主鍵關(guān)聯(lián),A和B互稱為同維表。同維表是一對(duì)一的關(guān)系,JOIN、LEFT JOIN和FULL JOIN的情況都會(huì)有。

典型例子:員工表和銷售員表。

3. 主子表

表A的主鍵與表B的部分主鍵關(guān)聯(lián),A稱為主表,B稱為子表。主子表是一對(duì)多的關(guān)系,只有JOIN和LEFT JOIN,不會(huì)有FULL JOIN。

典型例子:訂單和訂單明細(xì)。

這里說的主鍵是指邏輯上的主鍵,也就是在表中取值***的字段(組),一個(gè)表上可能有多個(gè)字段(組)都取值***(并不常見),可以認(rèn)為都是主鍵。不是一定是在物理表上建立的那個(gè)主鍵。

在SQL的概念體系中并不區(qū)分外鍵表和主子表,多對(duì)一和一對(duì)多從SQL的觀點(diǎn)看來只是關(guān)聯(lián)方向不同,本質(zhì)上是一回事。確實(shí),訂單也可以理解成訂單明細(xì)的外鍵表。但是,我們在這里要把它們區(qū)分開,將來在簡化語法和性能優(yōu)化時(shí)將使用不同的手段。

我們說,這三種JOIN已經(jīng)涵蓋了絕大多數(shù)等值JOIN的情況,甚至可以說幾乎全部有業(yè)務(wù)意義的等值JOIN都屬于這三類,把等值JOIN限定在這三種情況之中,幾乎不會(huì)減少其適應(yīng)范圍。

仔細(xì)考察這三種JOIN,我們發(fā)現(xiàn)所有關(guān)聯(lián)都涉及主鍵,沒有多對(duì)多的情況,可以不考慮這種情況嗎?

是的!多對(duì)多的等值JOIN幾乎沒有業(yè)務(wù)意義。

如果JOIN兩個(gè)表時(shí)的關(guān)聯(lián)字段沒有涉及到任何主鍵,那就會(huì)發(fā)生多對(duì)多的情況,而這種情況幾乎一定還會(huì)有一個(gè)規(guī)模更大的表把這兩個(gè)表作為維表關(guān)聯(lián)起來。比如學(xué)生表和科目表在JOIN時(shí),會(huì)有個(gè)成績表以學(xué)生表和科目表作為維表,單純只有學(xué)生表和科目表的JOIN沒有業(yè)務(wù)意義了。

當(dāng)寫SQL時(shí)發(fā)現(xiàn)多對(duì)多的情況,那大概率是這個(gè)語句寫錯(cuò)了!或者數(shù)據(jù)有問題!這條法則用于排除JOIN錯(cuò)誤很有效。

不過,我們一直在說“幾乎”,并沒有用完全肯定的說法,也就是說,多對(duì)多在非常罕見的情況下也會(huì)業(yè)務(wù)意義??膳e一例,用SQL實(shí)現(xiàn)矩陣乘法時(shí)會(huì)發(fā)生多對(duì)多的等值JOIN,具體寫法讀者可以自行補(bǔ)充。

笛卡爾積再過濾這種JOIN定義,確實(shí)非常簡單,而且簡單的內(nèi)涵將得到更大的外延,可以把多對(duì)多等值JOIN甚至非等值JOIN等都包括進(jìn)來。但是,過于簡單的內(nèi)涵無法充分體現(xiàn)出最常見等值JOIN的運(yùn)算特征。這會(huì)導(dǎo)致編寫代碼和實(shí)現(xiàn)運(yùn)算時(shí)就不能利用這些特征,在運(yùn)算較為復(fù)雜時(shí)(涉及關(guān)聯(lián)表較多以及有嵌套的情況),無論是書寫還是優(yōu)化都非常困難。而充分利用這些特征后,我們就能創(chuàng)造更簡單的書寫形式并獲得更高效率的運(yùn)算性能,我們將在以后的文章中逐步說明。

與其為了把罕見情況也被包括進(jìn)來而把運(yùn)算定義為更通用的形式,還不如把這些情況定義成另一種運(yùn)算更為合理。

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2017-12-26 15:33:24

JOINSQL運(yùn)算

2017-12-12 22:48:21

JOIN維度運(yùn)算

2017-11-15 06:36:25

JOINSQL運(yùn)算

2017-12-10 22:42:50

JOINSQL運(yùn)算

2018-01-01 23:28:37

JOIN維度數(shù)據(jù)分析

2018-01-10 15:25:43

JOIN維度SQL

2018-01-10 15:19:59

JOIN維度SQL

2017-12-10 22:48:53

JOIN運(yùn)算外鍵

2017-12-12 22:58:57

JOIN外鍵運(yùn)算

2011-09-23 09:49:48

拯救網(wǎng)管老克黑客拯救行動(dòng)第三季

2013-01-21 13:41:59

IBMdW

2014-04-15 13:52:23

移動(dòng)技術(shù)半月刊

2017-10-09 22:33:56

SQL等值分組有序分組

2017-10-18 22:34:33

SQL等值分組有序分組

2017-09-05 22:34:24

遍歷SQL運(yùn)算

2009-09-04 13:18:10

C#允許運(yùn)算符重載

2018-04-26 14:57:24

騰訊云音視頻

2018-01-18 20:47:18

CPU數(shù)據(jù)線程

2018-01-24 07:45:51

數(shù)據(jù)倍增分段列存

2017-09-13 08:45:33

遍歷SQL運(yùn)算
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)