天天看點

資料蔣堂 | JOIN運算剖析

資料蔣堂 | JOIN運算剖析

JOIN是SQL中用于多表關聯的運算,無論從程式員編寫還是資料庫實作角度來看,JOIN都是SQL中最難的運算。

其實,SQL對JOIN的定義非常簡單,就是對兩個集合(表)做笛卡爾積後再按某種條件過濾,寫出來的文法也就是A JOIN B ON ...的形式。原則上,笛卡爾積後的結果集應當是以兩集合成員構成的二進制組為成員,不過由于SQL中的集合成員總是有字段的記錄,而且也不支援泛型資料類型來描述成員為記錄的二進制組,是以就簡單地把結果集處理成由兩表記錄的字段合并後構成的新記錄集合。這也是JOIN一詞在英語中的願意,并沒有乘法(笛卡爾積)的意思。把結果集了解成二進制組還是字段合并的記錄,都不會影響本文的讨論。

JOIN定義中并沒有規定過濾條件的形式。理論上,隻要目标結果集是兩源集笛卡爾積的子集,都可以了解為JOIN運算。比如,我們可以計算 A JOIN B ON A<b></b>

<b>不過,有經驗的程式員都知道,現實中絕大多數JOIN都是等值JOIN,即過濾條件是一個或多個相等關系(多個之間是AND關系),文法形如A JOIN B ON A.ai=B.bi AND ...,其中ai和bi分别是A和B的字段。而前述例子中ON A<b></b></b>

<b><b>根據對空值的處理規則,等值JOIN還可以衍生出LEFT JOIN和FULL JOIN,而且一般會被分成一對一、一對多、多對多等幾種情況。這些正常術語在所有的SQL教科書都有,這裡就不再贅述了。</b></b>

<b><b></b></b>

<b><b>我們來考察下面三種等值JOIN:</b></b>

外鍵表

表A的某些字段與表B的主鍵關聯(所謂關聯,是指JOIN的過濾條件即由這些對應字段相等構成)。A表稱為事實表,B表稱為維表。A表中與B表主鍵關聯的字段稱為A指向B的外鍵,B也稱為A的外鍵表。外鍵表是多對一的關系,且隻有JOIN和LEFT JOIN,一般不會用到FULL JOIN。

<b><b>典型例子:帳戶交易記錄和帳戶基本資訊。</b></b>

同維表

表A的主鍵與表B的主鍵關聯,A和B互稱為同維表。同維表是一對一的關系,JOIN、LEFT JOIN和FULL JOIN的情況都會有。

<b><b>典型例子:員工表和銷售員表。</b></b>

主子表

表A的主鍵與表B的部分主鍵關聯,A稱為主表,B稱為子表。主子表是一對多的關系,隻有JOIN和LEFT JOIN,不會有FULL JOIN。

<b><b>典型例子:訂單和訂單明細。</b></b>

<b><b>這裡說的主鍵是指邏輯上的主鍵,也就是在表中取值唯一的字段(組),一個表上可能有多個字段(組)都取值唯一(并不常見),可以認為都是主鍵。不是一定是在實體表上建立的那個主鍵。</b></b>

<b><b>在SQL的概念體系中并不區分外鍵表和主子表,多對一和一對多從SQL的觀點看來隻是關聯方向不同,本質上是一回事。确實,訂單也可以了解成訂單明細的外鍵表。但是,我們在這裡要把它們區分開,将來在簡化文法和性能優化時将使用不同的手段。</b></b>

<b><b>我們說,這三種JOIN已經涵蓋了絕大多數等值JOIN的情況,甚至可以說幾乎全部有業務意義的等值JOIN都屬于這三類,把等值JOIN限定在這三種情況之中,幾乎不會減少其适應範圍。</b></b>

<b><b>仔細考察這三種JOIN,我們發現所有關聯都涉及主鍵,沒有多對多的情況,可以不考慮這種情況嗎?</b></b>

<b><b>是的!多對多的等值JOIN幾乎沒有業務意義。</b></b>

<b><b>如果JOIN兩個表時的關聯字段沒有涉及到任何主鍵,那就會發生多對多的情況,而這種情況幾乎一定還會有一個規模更大的表把這兩個表作為維表關聯起來。比如學生表和科目表在JOIN時,會有個成績表以學生表和科目表作為維表,單純隻有學生表和科目表的JOIN沒有業務意義了。</b></b>

<b><b>當寫SQL時發現多對多的情況,那大機率是這個語句寫錯了!或者資料有問題!這條法則用于排除JOIN錯誤很有效。</b></b>

<b><b>不過,我們一直在說“幾乎”,并沒有用完全肯定的說法,也就是說,多對多在非常罕見的情況下也有業務意義。可舉一例,用SQL實作矩陣乘法時會發生多對多的等值JOIN,具體寫法讀者可以自行補充。</b></b>

<b><b>笛卡爾積再過濾這種JOIN定義,确實非常簡單,而且簡單的内涵将得到更大的外延,可以把多對多等值JOIN甚至非等值JOIN等都包括進來。但是,過于簡單的内涵無法充分展現出最常見等值JOIN的運算特征。這會導緻編寫代碼和實作運算時就不能利用這些特征,在運算較為複雜時(涉及關聯表較多以及有嵌套的情況),無論是書寫還是優化都非常困難。而充分利用這些特征後,我們就能創造更簡單的書寫形式并獲得更高效率的運算性能,我們将在以後的文章中逐漸說明。</b></b>

<b><b>與其為了把罕見情況也包括進來而把運算定義為更通用的形式,還不如把這些情況定義成另一種運算更為合理。</b></b>

資料蔣堂 | JOIN運算剖析

清華大學計算機碩士,著有《非線性報表模型原理》等,1989年,中國首個國際奧林匹克數學競賽團體冠軍成員,個人金牌;2000年,創立潤乾公司;2004年,首次在潤乾報表中提出非線性報表模型,完美解決了中國式複雜報表制表難題,目前該模型已經成為報表行業的标準;2014年,經過7年開發,潤乾軟體釋出不依賴關系代數模型的計算引擎——集算器,有效地提高了複雜結構化大資料計算的開發和運算效率;2015年,潤乾軟體被福布斯中文網站評為“2015福布斯中國非上市潛力企業100強”;2016年,榮獲中國電子資訊産業發展研究院評選的“2016年中國軟體和資訊服務業十大領軍人物”;2017年, 自主創新研發新一代的資料倉庫、雲資料庫等産品即将面世。

資料蔣堂

《資料蔣堂》的作者蔣步星,從事資訊系統建設和資料處理長達20多年的時間。他豐富的工程經驗與深厚的理論功底互相融合、創新思想與傳統觀念的互相碰撞,虛拟與現實的互相交織,産生出了一篇篇的瀝血之作。此連載的内容涉及從資料呈現、采集到加工計算再到存儲以及挖掘等各個方面。大可觀資料世界之遠景、小可看技術疑難之細節。針對資料領域一些技術難點,站在研發人員的角度從淺入深,進行全方位、360度無死角深度剖析;對于一些業内觀點,站在技術人員角度闡述自己的思考和了解。蔣步星還會對大資料的發展,站在業内專家角度給予預測和推斷。靜下心來認真研讀你會發現,《資料蔣堂》的文章,有的會讓使用者避免重複前人走過的彎路,有的會讓攻城獅面對紮心的難題茅塞頓開,有的會為初入行業的讀者提供一把開啟資料世界的鑰匙,有的甚至會讓業内專家大跌眼鏡,産生思想交鋒。

<b><b>原文釋出時間為:2017-11-8</b></b>

本文作者:蔣步星