第38期:JOIN延伸 - 維度其它應(yīng)用
明確維度定義后,還可以換一種更清晰的方式來(lái)審視數(shù)據(jù)庫(kù)的結(jié)構(gòu)。
這是我們常見(jiàn)的E-R圖:
E-R圖是個(gè)網(wǎng)狀結(jié)構(gòu),實(shí)體(表)之間的外鍵關(guān)系直接畫(huà)在圖上,當(dāng)實(shí)體較多時(shí)這個(gè)圖就會(huì)顯得非常零亂,關(guān)聯(lián)線很隨意,任何兩個(gè)實(shí)體之間都有可能發(fā)生關(guān)聯(lián),表現(xiàn)出來(lái)的數(shù)據(jù)結(jié)構(gòu)耦合度很高。在增加刪除實(shí)體時(shí)就要考慮與之關(guān)聯(lián)的所有其它實(shí)體,很可能發(fā)生遺漏關(guān)聯(lián)或循環(huán)關(guān)聯(lián)的現(xiàn)象。
一
而如果把維度抽取出來(lái)之后,我們可以使用總線式的結(jié)構(gòu)圖:
所有維度單獨(dú)列出來(lái)處于中心地位,實(shí)體(表)只和維度發(fā)生關(guān)聯(lián),實(shí)體之間沒(méi)有直接的關(guān)聯(lián)線,數(shù)據(jù)結(jié)構(gòu)的耦合度看起來(lái)很低。增加刪除實(shí)體時(shí)不會(huì)影響到其它實(shí)體,不會(huì)發(fā)生遺漏關(guān)聯(lián)和重復(fù)關(guān)聯(lián)。
不過(guò),需要指出的是。無(wú)論是E-R圖還是總線圖,只要畫(huà)正確時(shí),其中的關(guān)聯(lián)線數(shù)量是差不多的,這是數(shù)據(jù)本身的關(guān)系決定的??偩€圖并不會(huì)比E-R中的關(guān)聯(lián)線更少,但改變了看待方法后會(huì)更清晰。
二
為了提供關(guān)聯(lián)查詢(xún)能力,有些BI產(chǎn)品將表間關(guān)聯(lián)關(guān)系(相當(dāng)于一個(gè)局部E-R圖)直接暴露給業(yè)務(wù)人員,這不是個(gè)好辦法,業(yè)務(wù)人員難以理解E-R圖,這個(gè)方案的可用性很差。如果能夠由業(yè)務(wù)人員選擇了數(shù)據(jù)項(xiàng)(字段)后就自動(dòng)建立出合理的關(guān)聯(lián),那樣可用性就能提高很多了。
有了維度概念,就可以一定程度地實(shí)現(xiàn)這一目標(biāo)。
業(yè)務(wù)人員任意選擇了字段之后,我們可以找出這些字段所在表,再在這些表之間尋找同維字段(優(yōu)先選擇主鍵),然后使用這些同維字段建立JOIN關(guān)系。當(dāng)某個(gè)表上只有***的字段和另一表的主鍵字段同維時(shí),那么基于這兩個(gè)字段建立的JOIN關(guān)系在絕大多數(shù)情況下都是正確合理的。而且,在數(shù)據(jù)結(jié)構(gòu)不是特別復(fù)雜的時(shí)候,兩表之間只有***字段同維的條件也常常能夠滿足,這時(shí)候就真地能只基于數(shù)據(jù)項(xiàng)自動(dòng)建立正確的關(guān)聯(lián)關(guān)系,有些BI產(chǎn)品確實(shí)是這么做的。
不過(guò),這種辦法不能處理同表自關(guān)聯(lián)和表間有多個(gè)同維字段的情況,以及多次遞歸關(guān)聯(lián)的問(wèn)題。想要完善地解決問(wèn)題,還是需要基于DQL語(yǔ)法來(lái)實(shí)現(xiàn)關(guān)聯(lián)。
三
上面的討論中,我們會(huì)把發(fā)現(xiàn)的同維字段JOIN起來(lái),DQL語(yǔ)法也是這樣,只要同維的(廣義)字段就可以JOIN。這樣的JOIN一定有業(yè)務(wù)意義嗎?
是的,只要是同維字段,JOIN起來(lái)總能想出合理業(yè)務(wù)意義。反過(guò)來(lái),也只有同維字段之間可以JOIN,不同維字段的JOIN是沒(méi)有業(yè)務(wù)意義的,不過(guò)SQL并不禁止,只要數(shù)據(jù)類(lèi)型相同就可以JOIN。字段同維和JOIN有業(yè)務(wù)意義是等價(jià)的,DQL在這方面可以確保這一點(diǎn)。
DQL中GROUP BY總是要對(duì)應(yīng)著ON(如果單表可以看成是省略O(shè)N),也就是說(shuō),GROUP BY總是針對(duì)某個(gè)維度進(jìn)行的。事實(shí)上也是這樣,針對(duì)測(cè)度的分組運(yùn)算沒(méi)有業(yè)務(wù)意義,不過(guò)SQL并沒(méi)有明確出維度和測(cè)度的概念,也不會(huì)禁止這個(gè)運(yùn)算。DQL則確保了不會(huì)發(fā)生無(wú)業(yè)務(wù)意義的分組。
利用這個(gè)特點(diǎn),可以提高分組運(yùn)算的性能。維度可能的取值是由維表長(zhǎng)度決定的,而維表是事先知道的,這樣在分組時(shí)可以采用類(lèi)似基數(shù)排序法的手段提速,當(dāng)然,針對(duì)維度的排序運(yùn)算也可以用這種辦法。不過(guò),這個(gè)算法細(xì)節(jié)與本篇主題相關(guān)性較低,這里就不詳細(xì)說(shuō)明了。