SQL的困難源于關(guān)系代數(shù)

在結(jié)構(gòu)化數(shù)據(jù)處理領(lǐng)域,SQL無(wú)疑是應(yīng)用最廣泛的工作語(yǔ)言,不僅被所有關(guān)系數(shù)據(jù)庫(kù)采用,許多新進(jìn)的大數(shù)據(jù)平臺(tái)也將實(shí)現(xiàn)SQL作為目標(biāo)。但現(xiàn)實(shí)是,面對(duì)當(dāng)前紛雜的計(jì)算查詢需求,SQL在很多方面并不夠好用。一般為人詬病的SQL的過(guò)程性問(wèn)題,其實(shí)并不是最關(guān)鍵的問(wèn)題,SQL的更大困難來(lái)源于其理論基礎(chǔ),即關(guān)系代數(shù)。


關(guān)系代數(shù)是一種代數(shù)體系。拋開嚴(yán)格定義代數(shù)體系的概念,通俗地解釋。人們?yōu)榻鉀Q某種運(yùn)算問(wèn)題,定義了一些數(shù)據(jù)對(duì)象及針對(duì)這些數(shù)據(jù)對(duì)象的一套運(yùn)算規(guī)則,確保這些運(yùn)算的封閉性和自洽性,就可以稱為一種代數(shù)體系了。比如說(shuō)我們熟悉的有理數(shù)及其上的四則運(yùn)算就是一種用于解決日常生活中數(shù)值計(jì)算需求的代數(shù)體系。封閉性是指計(jì)算結(jié)果必須仍然是定義過(guò)的數(shù)據(jù)對(duì)象,比如有理數(shù)的四則運(yùn)算結(jié)果仍然是有理數(shù)。而自洽性指這些運(yùn)算不能出現(xiàn)矛盾的結(jié)果,比如我們要約定不能除以0,否則把某個(gè)數(shù)除以0規(guī)定成任何數(shù)都會(huì)推出邏輯矛盾來(lái)。

注意,這里說(shuō)的數(shù)據(jù)對(duì)象,和程序設(shè)計(jì)面向?qū)ο罄碚撝袛?shù)據(jù)對(duì)象不太一樣。前者主要強(qiáng)調(diào)數(shù)據(jù)上的運(yùn)算,而后者更多強(qiáng)調(diào)對(duì)象的封裝性、繼承性和重載能力。前者是為了更好的描述和實(shí)施數(shù)據(jù)運(yùn)算,后者則主要是為了代碼復(fù)用。


代數(shù)體系設(shè)計(jì)得好與不好,嚴(yán)重影響我們實(shí)施計(jì)算的方便度和效率!

舉兩個(gè)例子:

1. 我們從小學(xué)過(guò)的算術(shù)體系都采用阿拉伯?dāng)?shù)字,用來(lái)表示數(shù)值和做四則運(yùn)算都很方便,但試想如果換成羅馬數(shù)字會(huì)是個(gè)什么感覺?

2. 所有整數(shù)乘法都可以用加法表示,我們?cè)谒阈g(shù)體系中引入了乘法來(lái)表示若干個(gè)相同數(shù)相加這種運(yùn)算,就可以發(fā)明九九表來(lái)做而不必硬加,效率顯著提高。

要讓計(jì)算機(jī)實(shí)施計(jì)算,還需要一套基于代數(shù)體系的形式化語(yǔ)言,用戶把計(jì)算目標(biāo)按約定的語(yǔ)法符號(hào)寫成代碼,就可以由計(jì)算機(jī)執(zhí)行了。而用計(jì)算機(jī)解決問(wèn)題的過(guò)程,也可以理解為把題目解法翻譯成某種形式化語(yǔ)言的過(guò)程。如果代數(shù)體系及其形式化語(yǔ)言設(shè)計(jì)得不好,就可能發(fā)生翻譯問(wèn)題解法的難度大于解決問(wèn)題本身的現(xiàn)象!用羅馬數(shù)字來(lái)實(shí)施四則運(yùn)算就是這個(gè)結(jié)果。


關(guān)系代數(shù)就是用來(lái)實(shí)現(xiàn)批量結(jié)構(gòu)化數(shù)據(jù)計(jì)算的代數(shù)體系,其形式化語(yǔ)言就是SQL。講述關(guān)系代數(shù)和SQL原理的資料很多,這里就不再贅述了。

那么用SQL解決結(jié)構(gòu)化數(shù)據(jù)運(yùn)算的效果如何呢?

人們通常關(guān)心兩個(gè)效率問(wèn)題。一是運(yùn)算的描述效率,二是運(yùn)算的執(zhí)行效率。這兩個(gè)效率很容易理解,如果描述效率太低,就意味著開發(fā)成本太高,很難寫出程序進(jìn)行計(jì)算;而如果執(zhí)行效率低,則需要運(yùn)行很久才能得到結(jié)果,那實(shí)用價(jià)值也就大打折扣了。實(shí)際上,執(zhí)行高效在本質(zhì)上也是個(gè)描述問(wèn)題,在軟件層面不可能提高硬件性能,但可能設(shè)計(jì)出更高效的算法,那么這個(gè)語(yǔ)言不能限制我們寫出高效算法。


遺憾的是,面對(duì)較復(fù)雜的大數(shù)據(jù)運(yùn)算,SQL在這兩方面表現(xiàn)都很差,我們分別舉兩個(gè)并不復(fù)雜的例子說(shuō)明:

1. 找出一支股票最長(zhǎng)連續(xù)上漲了多少天

這個(gè)問(wèn)題對(duì)于Java或C++程序員來(lái)講非常簡(jiǎn)單:做個(gè)初值為0的計(jì)數(shù)器,把數(shù)據(jù)按日期排序后遍歷,發(fā)現(xiàn)上漲就將計(jì)數(shù)器加1,下跌則清0,最后看這個(gè)計(jì)數(shù)器出現(xiàn)過(guò)的最大值,這是個(gè)很自然的思路。但是用SQL實(shí)現(xiàn)就太困難了。關(guān)系代數(shù)延用了數(shù)學(xué)上的無(wú)序集合概念,數(shù)據(jù)排序只在輸出時(shí)有效,無(wú)法規(guī)定數(shù)據(jù)的遍歷次序,也就無(wú)法實(shí)施上述的自然思路。需要人為地制造出日期的序號(hào)后,再產(chǎn)生一個(gè)分組標(biāo)志,把上漲的日期和前一天分成一組,下跌的日期分到另一組,然后計(jì)算最大的分組COUNT()值,實(shí)現(xiàn)思路很難理解。這就發(fā)生前面所說(shuō)的翻譯問(wèn)題解法的難度大于解決問(wèn)題本身的現(xiàn)象了。

?2. 從10億條數(shù)據(jù)中找出最大的前10名

我們知道,這樣的問(wèn)題是不需要把10億行數(shù)據(jù)全部排序的。先產(chǎn)生一個(gè)有10個(gè)成員的空集合,然后遍歷數(shù)據(jù),過(guò)程中始終保持這個(gè)小集合是當(dāng)前已遍歷過(guò)數(shù)據(jù)中最大的10個(gè),這樣整個(gè)10億行數(shù)據(jù)只要遍歷一次,內(nèi)存占用很小,運(yùn)算性能很好。但關(guān)系代數(shù)中沒有顯式的集合數(shù)據(jù)類型,無(wú)法描述這個(gè)算法,只能把10億行數(shù)據(jù)大排序再取出前10后,剩下的已排序的數(shù)據(jù)沒有用了。10億行大排序的成本很高,如果內(nèi)存裝不下則還會(huì)設(shè)計(jì)多次外存數(shù)據(jù)倒換的問(wèn)題,性能會(huì)嚴(yán)重下降。這就會(huì)發(fā)生我們明知有好的算法卻無(wú)計(jì)可施的尷尬局面。這種情況常常就只能寄希望于數(shù)據(jù)庫(kù)在工程上的優(yōu)化,但情況復(fù)雜的SQL會(huì)超出數(shù)據(jù)庫(kù)的優(yōu)化能力(比如在分組中取每組的前10名)。

SQL中類似的問(wèn)題還很多,遠(yuǎn)遠(yuǎn)不像傳說(shuō)中的那么強(qiáng)悍。限于篇幅我們不能一一羅列,以后會(huì)逐步撰文深入剖析。


在運(yùn)算簡(jiǎn)單的情況,并且性能要求不高時(shí),用SQL還是比較方便的,畢竟掌握者眾多,相關(guān)軟件也很豐富。但現(xiàn)代應(yīng)用中的數(shù)據(jù)需求越來(lái)越復(fù)雜,數(shù)據(jù)量也越來(lái)越大,繼續(xù)采用SQL就會(huì)嚴(yán)重影響工作效率了。而且,SQL的不適應(yīng)并非實(shí)現(xiàn)層面的問(wèn)題,而是其基礎(chǔ)理論的問(wèn)題,這不是在工程上進(jìn)行優(yōu)化就能解決的。面臨當(dāng)前的數(shù)據(jù)運(yùn)算需求,關(guān)系代數(shù)顯得過(guò)于簡(jiǎn)單了,需要從數(shù)學(xué)上進(jìn)行徹底的革新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評(píng)論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,740評(píng)論 3 420
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評(píng)論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,931評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,321評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評(píng)論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,533評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,082評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,891評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,067評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,319評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評(píng)論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,794評(píng)論 3 394
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,076評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容