關係型數據庫的統治

前文談到開發SaaS最大的挑戰是實現一個可擴展的多租戶數據庫模型,黑屋對此深有同感。黑屋背後的數據庫模型也是基於多租戶的理念搭建的, 我們稱之爲MDB,即Multi-Tenancy DataBase。 架構MDB是個既令人興奮又充滿失望的過程,有很多新奇的想法不時涌現, 但沒多久你便會失望的發現這些想法要麼別人早已實踐過了,要麼有更好的替代方案。然而整個過程讓黑屋學到了更多的數據庫知識, 並且領悟了一些本質性的東西。這將會是一次漫長的旅行,在繼續前進之前,黑屋覺得有必要先把這些心得記錄下來,也分享給大家。

介紹

大多數的軟件開發離不開數據庫,如果你把軟件定義爲“程序”和“數據”,如何存儲數據一直是軟件開發過程中最值得去思考的問題。上世紀 80年代來,關係型數據庫已經讓大家從這個複雜的問題中解放了出來。至少對一部分開發者來說,他們再也不用愁數據存儲這個問題了, 以至那些企業應用軟件的用戶已經完全忽視了數據存儲。他們更熱衷於繪製業務流程圖以及對UI界面的指手畫腳, 數據存儲在他們的印象中就如同EXCEL中的幾個SHEET那樣理所當然。然而,理所當然的事物往往是最重要,也是最難實現的。 黑屋認爲業務邏輯和UI是一堆沒有價值的“管道代碼”,因此應儘可能實現自動生成。

在另一個陣營中,一羣人一直在挖掘數據存儲的潛力,他們造就了屬於這個時代的新名詞:“大數據”, “Hadoop”, “NoSQL”, 等等。他們更接近IT的本質(開發實質的信息處理軟件而非管道軟件),憑藉紮實的技術和進取心,撼動着強大的關係型數據庫。 然而這些IT新名詞僅僅是一段時期內的流行詞彙,還是能真正帶來一些變革?無論怎樣,它們確實影響到了如今的應用開發者。 “數據存儲”這個問題被重新提出來:突然多了那麼多數據庫,到底選擇哪個?看待這個問題不能只從技術層面上, 因爲追隨新銳事物總能給人以先進的感覺,從而獲得超出實際的評價。

因此我們也不能僅僅將對比不同數據庫的特性來作爲挑選的依據(而且這樣的文章已經夠多了)。如果我們重新回顧一下數據庫發展的歷史, 瞭解各個階段它要解決的問題,熟悉更多關於數據庫本質的內容,這將有助於我們做出正確的選擇。黑屋冀希望以此能讓企業應用軟件領域的用戶重新重視數據存儲; 也希望那些年輕的互聯網從業者更多的關注數據處理軟件的前塵往事,去創造更令人激動的未來。

本系列以數據庫發展歷史爲主線,分別以5篇博客依次介紹:“關係型數據庫的統治”,“OLAP浪潮”,“列式數據庫的逆襲”,“互聯網時代的百家爭鳴”, 以及最後“MDB的多租戶數據模型”。

本文是這個系列的第一篇,首先介紹一些早期的數據庫模型,然後重點介紹關係型模型以及關係型數據庫。 雖然主題是數據庫模型,但如果不涉及底層的物理模型(物理介質上的數據結構),是很難描述全面的,同時爲了避免過於技術, 對數據物理模型的描述只會點到爲止。最後討論一些關係模型之後出現的數據模型,主要以實體-關係模型爲主。

早期的數據庫模型

我們在討論數據庫模型的時候是不能不提承載它的物理設備的,雖然數據庫模型從一開始就想擺脫硬件對它的限制,做到所謂的硬件獨立, 但一旦放諸於實際應用,你就必須得考慮硬件的實際承載能力。事實上,在計算機發展過程中,硬件和軟件總是相輔相成的: 硬件是軟件運行的容器,容器的形狀和大小決定了軟件的設計;然而軟件反映的是人類的思維,思維不受限制, 因此軟件就能反過來促使硬件按照它的定義去發展。早期的數據庫模型正是在磁盤被廣泛應用的基礎上發展起來的。

相對於磁帶的順序訪問(Sequential Access),磁盤提供的直接訪問(Random Direct Access)爲軟件提供了更多的思維空間。 我們現在熟悉的文件系統也是在磁盤的基礎上實現的,思考一下,這種我們習以爲常的文件夾包含文件夾和文件的層級架構是如何實現的? 這是個非常有趣的話題,但不在本文的討論範圍內。然而我們接下來要談的第一個數據庫模型和文件系統有着非常類似的層級結構, 它的名字就叫層級數據模型。

層級數據模型是以樹形結構組織數據的,要求每個子節點只能擁有唯一的父節點,從這個意義上它和現在的文件系統是一樣的。 然而作爲一個數據庫系統,和文件系統最大的不同在於它要有能力對現實中的事物模型化。我們對現實世界中的事物往往存有一個概念上的抽象, 例如,公司內部的組織結構在我們的概念中就是一個層級,你能圖像化不同的部門、人、以及他們的上下級關係。 這種概念上的抽象需要進一步抽象到邏輯層面,即去除那些無關緊要的部分(比如剛從你腦中一閃而過的各種圖像),以便我們能把精力集中在問題本身。 經過上述思維過程後,我們便能畫出類似圖1中的層級數據模型。

 文件系統和數據庫系統到底有什麼區別?從本質上它們是一樣的,文件系統是模擬了文件夾和文件的數據庫,數據庫是更細節化的文件系統。 有趣的是來自這兩個陣營的開發者至今還在相互對峙中。

圖1. 層級數據模型

接下來的問題是如何在計算機系統中實現這樣一個層級模型,這就是計算機軟件(或者說數據庫)所要負責的事情,即將數據邏輯模型和數據物理模型對應起來。 要了解這種對應關係是如何實現,我們有必要先簡單描述一下磁盤的工作原理。

磁盤顧名思義是一個表面帶磁性的圓形盤片,它能繞着中心軸快速的旋轉;磁盤表面的各個同心圓被稱爲磁道,二進制數據就是分散保存在這些磁道上; 磁頭和磁臂負責定位處於特定磁道中的特定扇區。爲了簡化,假設我們的磁盤只有一個磁道,這個磁道被分爲12個扇區,分別標上從0到11的編號(參見圖2)。

圖2. 單磁道磁盤

我們的單道磁盤如果以每分鐘10,000轉的速度旋轉(RPM),那麼通過簡單的換算,便得出磁頭從指向扇區6到指向扇區0所需的時間爲3ms。 扇區0中正好保存着圖1層級結構中的根節點,即所有的“集團”信息。假設每個扇區的大小是512 Byte,每個“集團”信息需要100 Byte的長度, 那麼在扇區0中可以保存5個“集團”,分別是“集團1”到“集團5”(參見圖3)。如果我要看“集團1”的信息,那麼只需截取前100 Byte長的數據, 這裏面就包含了如“集團名字”等固有屬性信息,它們佔據88 Byte長;在剩下的12 Byte中,分別保存了3個指向子節點的指針,每個指針4 Byte長, 它們分別指向保存“公司1”、“公司2”、“公司3”的扇區;“公司2”對應的扇區10保存了“公司2”的屬性信息及其部門子節點所在的扇區編號, 這裏“財務部”和“IT部”的數據被分別保存在扇區4和扇區5。這樣通過層級間的導航,我們可以快速遍歷整個層級結構。 粗略估算一下,在不考慮緩存的情況下,獲取集團1下面公司2的IT部門信息大概需要9ms(按導航指引,訪問扇區0、10、5), 不算太慢,是不是?

圖3. 導航型數據庫

這種通過數據記錄之間的直接指引並提供引導式訪問路徑的數據庫被稱爲導航型數據庫(Navigational Database)。 考慮到上世紀60年代中期,磁盤速度還遠沒有現在那麼快的情況下,以這種物理模型實現的數據庫還是能提供可接受的性能的。 我們也看到,將層級數據模型對應到這種導航型的物理數據模型是比較直接的,沒有涉及複雜的數據結構和轉換, 這恰恰能說明這個時期的數據庫模型受限於硬件能力。

導航型數據庫的工作方式和現在導航軟件很類似:向前1000米,右轉,向前500米,左轉,向前100米,到達。

雖然現實世界中有許多事物本身就是以層級組織的,例如, 除了組織結構外,製造行業中的物料清單(BOM)也是個天然的層級結構, 然而層級結構並是一個通用數據模型。 還是以一個企業的組織結構爲例,如果這個集團下面的所有公司共享一個財務部和IT部(這在現代企業架構中很常見), 那麼我們就得到如圖4這樣的網狀模型。與層級數據模型不同,網狀數據模型允許子節點有多個父節點,這樣便能實現“多對多”的實體對應關係。

圖4. 網狀數據模型

網狀數據模型還是可以輕鬆的用導航型數據庫實現,這並不會添加太多的難度,只要在子節點上存有指向其各個父節點的指針即可。 然而無論是層級數據模型還是網狀數據模型,其訪問數據的路徑總是被嚴格限制的,你只能基於它給出的路徑,一個節點一個節點的去遍歷。 分別有2個著名的數據庫採用這兩種數據模型:其一是GE於1964年發佈的Integrated Data Store(IDS),它是個網狀數據庫; 其二是IBM於1968發佈的Management Information System(MIS),它是個層級數據庫。值得注意的是,MIS至今仍然被廣泛應用於銀行和電信領域。

還有一個最常見的層級數據庫就是WINDOWS系統中的註冊表,它被用於保存WINDOWS應用程序的配置信息。

雖然這兩種數據模型都將被隨之而來的關係型模型取代,但是它們代表了數據庫的原型,並一直影響着以後的數據庫實現。 即便是今天,我們依然能從這些早期的設計和實現中獲取無窮無盡的靈感。如今流行的NoSQL數據庫也多少讓人覺得是在“反祖”中獲得的新生。 在談論那些形形色色的互聯網數據庫之前,我們還是需要先花點時間來了解關係型數據模型。

關係型數據模型

數據庫模型的歷史雖然不是起源於關係型模型,但必須得說關係型數據庫曾統一了所有的數據庫模型,並一直統治至今。 關係型模型進入人們視野的具體時間是E.F.Codd在1970年發表的論文: "A Relational Model of Data for Large Data Bank"

很多人對關係型數據模型的印象是表和字段,並還能想到的是表與表之間通過某些字段可以關聯起來。似乎正因爲這樣,關係型數據庫才被冠於這個名字。 然而關係型數據模型中的“關係”在英文中對應的單詞“Relation”是一個抽象的數學概念,它既不是獨指2個表之間的關係,也不等價於一個二維表(雖然習慣於以二維表來表示)。 數學中關於Relation的定義是這樣的:給定n個集合S1、S2、 S3、 ...、 Sn, R是一個n元數組(n-tuples),它的第一個元素取自集合S1,第二個元素取自集合S2,以此類推。我們將R稱之爲基於該n 個集合的一個Relation,Sj爲R的第j個域(Domain)。

 換種方式表述:R是集合S1×S2×S3× ...×Sn笛卡爾積的一個子集。

很難將上述的定義與現在的關係型數據庫聯繫起來,然而這正是Codd在1970年那篇論文中的精華, 十年後,Larry Ellison也正是根據這篇論文開發了ORACLE數據庫。 Relation完全是個邏輯層面上的概念,將一個邏輯數據模型變成一個數據庫產品,需要在工程方面付出巨大的努力,並最終得到市場認可。 我們必然好奇是什麼樣的內在因素使關係型模型能得到工程師和市場的一致認可,即Codd當時引入關係型模型是要解決什麼問題?

需要解決的問題自然是層級數據模型和網狀數據模型的不足,即數據對底層物理存儲結構還是有很強的依賴性。 從前面對這兩個模型的描述中我們發現,在處理實體間關係這個問題上,它們都是以磁盤的扇區號爲直接指向,這當然可以說是爲了保證性能, 但在實際應用過程中,會帶來諸多不便。例如,你只能被限制在有限的幾條訪問路徑上,更大的問題還在於對模型的調整很有可能會同時牽涉磁盤重組和應用程序重寫。 Codd指出了當時數據庫系統中需要消除的三大數據依賴。

  • 排序依賴:數據總是以一定的順序保存在磁盤上,例如以“集團號”從小到大的順序存儲, 應用程序如果只能按存儲順序處理數據,那麼哪天突然要求按另一種順序排列(如“集團名字”),它很有可能會運行失敗。 這就要求數據庫系統能將數據的存儲順序和展現順序獨立開。
  • 索引依賴:索引被用來加快對數據的查詢和遍歷操作,但同時它會降低數據的插入性能。單從信息角度看,索引是個冗餘部件, 因此即使在沒有索引的情況下,應用程序應該也能正確運行(只是帶來性能的影響)。數據庫系統應該要保證,無論是添加還是刪除索引, 都不會導致應用程序的調整,即消除其對索引的依賴。
  • 訪問路徑依賴:層級和網狀數據庫系統的訪問路徑都是一開始設計好的,應用程序只能被限制在這些規定好的訪問路徑上。 例如:如果想取得“部門”信息,那隻能根據預設好的路徑先通過“集團”,再到“公司”,最後找到所要的信息;反過來, 如果想根據“部門”信息找到對應的“集團”信息,那麼就先得建立“部門”的索引,然後設置從“部門”到“公司”最後到“集團”的導航指引。 這些訪問路徑都必須在一開始設計數據庫的時候考慮到,並生成對應的訪問程序,如果後期對數據模型有調整或者增加新的訪問路徑, 都意味着數據庫和應用程序的雙重調整。因此數據庫系統要有能力提供所有可能的訪問路徑,消除對訪問路徑的依賴。
 如果你整理過個人電腦中的文件夾,你會經歷同樣的煩惱:你可以將文件按你所經歷過的項目來組織,也可以按文件對應於你專業的知識框架來組織, 討厭的是你只能選擇其中一種文件夾結構;如果你突然哪天想按年份層級來查閱文件,你會發現系統根本無法做到。

基於當時數據庫系統以上三點的不足,Codd進一步總結出,將來的數據庫系統要能做到“對稱探索”(Symmetric Exploitation), 即用戶可以根據任何已知的屬性組合去探索剩下的未知屬性。我們有理由相信關係型模型的靈感來源於數學,而正因爲數學包羅萬象, 所以有能力去實現各種語義級別的數據探索。從Relation的數學定義中可以看出它屬於集合,那麼對於集合的所有操作包括: 交集、並集、子集等應可用於Relation。Codd在此基礎上提出了“關係代數”(Relation Algebra),其中的一些操作, 如:Projection, Join, Restriction爲後來SQL語言的形成提供了理論基礎。

 這裏的“探索”包含查詢、更新、插入和刪除等操作;對稱性不是體現在性能上,而是在訪問路徑上。

很明顯,Codd當時提出的關係型模型只是一種理論框架,它最大的成就在於賦予數據庫系統一個科學內核。 即定義了數據庫系統應該能而且必須要做到的事情,因爲只有這樣它才能如同物理學一樣,與數學契合;才能成爲一種真正的信息科學技術。 那麼接下來,留給工程師們的就是這麼一個遠大而又宏偉的目標——如何在計算機系統中實現或者接近這個模型。問題是憑藉當時的計算機性能, 要實現關係型數據模型是件非常具有挑戰的事情。然而正是其科學內核賦予它強大的吸引力,使得在以後的十年裏,雨後春筍般誕生了許多號稱關係型數據庫的產品。

關係型數據庫

開發關係型數據庫的難點在哪裏?我們先從“對稱探索”說起,要實現這個特徵,你必須要對一個Relation提供所有可能的訪問路徑。 例如:一個二元關係(x, y), 有2條訪問路徑:通過x來訪問y(x->y), 和通過y來訪問x(y->x)。由此我們可以推斷,一個n元關係的訪問路徑總數爲n的階乘(1×2...×n)。 如何在計算機中實現一個n元關係的所有訪問路徑?最直接的想法就是用一張二維表的形式來表現一個Relation:表的每一行代表了這個Relation的一個元組(Tuple), 而每一列對應一個域(Domain);每一行可通過一個獨一無二的值唯一指定,包含這些值的域稱爲主碼(Primary Key)(參見圖5,主碼域標有下劃線)。

這裏存在的問題是Domain很多時候對應的不是單值,圖5中,“包含公司”這列說明,一個集團可以擁有多家公司。當然你可以將所有公司到保存在一個Domain中, 用逗號將它們區分開。然而如果一個公司下又可以有多個部門(如“包含部門”),這種情況下你會發現很難在一張表中表現哪個部門對應哪個公司。 如果在“包含公司”這個域中保存的是一個指針,指向其所包含的所有公司,然後公司再保存指向部門的指針,這就又回到導航數據庫了, 即還是限定了訪問路徑,無法實現對稱探索。


圖5. 關係模型規範化

解決這個問題的辦法是通過對關係模型進行規範化(Normalize),具體過程如下:將那些多值的Domain剝離出來,爲之建立一個獨立的Relation, 這個Relation的主碼是一個複合主碼,其中一部分是來自父Relation的主碼;依次執行相同的操作,直到所有的Relation都只含有單值Domain爲止。 我們對圖5中上面的Relation進行規範化操作後便得到下面的3個Relation: Group和Company間是一對多的關係,體現的是一種層級結構; Company和Department之間是多對多關係,體現的是一種網狀結構。通過這種轉換後,你會發現對稱探索的能力被保留了下來, 邏輯上,你可通過任何已知的屬性訪問剩下未知屬性,不需要指針指引。

接下來的問題是如何將這3張二維表(Relation)保存到磁盤上。最簡單的想法是分別以3個文件保存,這當然是對的,只是會面臨嚴重的性能問題。 例如:你想取得部門名爲“IT部1”的集團名和公司名,那麼你必須依次打開Department,Company,和Group對應的3個文件, 並對文件中包含的條目進行逐一比對。這種算法效率顯然不夠高,而且一旦數據量變得很大,這種數據庫將變得無法操作。

避免這種全文件掃描的辦法是先將文件分成更小的單元,稱之爲“頁”(Page),一個Page的大小是恆定的,一般設爲4KB;然後對這些Page建立索引, 根據索引能快速獲知滿足條件的數據被保存在哪些Page中。數據庫索引的工作原理和查字典是完全一樣的,像漢語字典就有好幾個索引:讀音,部首,筆畫等等; 每種索引的編排方式都不同,但最終一定是指向一個頁碼。數據庫的索引也可以用不同技術基於不同的Domain去建立。 這裏只介紹一種使用最廣泛的索引技術——平衡二叉樹(參見圖6)。


圖6. 平衡二叉樹

圖6中的樹形結構每個節點是一個Page,Page內部保存我們要查找的部門名字,假設我們的Page容量很小,根節點只保存了兩個部門名字: “IT部1”和“財務部”。我們定義大於等於“IT部1”且小於“財務部”的部門名保存在根節點的左孩子節點中;大於等於“財務部”的部門名保存在右孩子節點中。 這樣我們的樹的第二層節點中的第一個Page保存了3個部門的名字,其中第一個值“IT部1”其對應的指針直接指向實際的數據記錄—— 表Department中滿足部門名字是“IT部1”的行。基於平衡二叉樹,我們的查詢只需讀取3個Page。當獲取對應的集團主碼和公司主碼後,以同樣的方式, 我們可以獲取公司名和集團名。

 怎麼來比較部門名的大小完全可以由你自己設定,這裏根據英文字母的排列順序,如果是漢字則取其拼音的首字母。

平衡二叉樹之所以被冠之“平衡”是因爲它左右兩邊的層級保持一致,一旦達到這種平衡效果,所有的查詢都是二分查找,算法複雜度爲O(logn)。 但維持左右平衡並不是件容易的事情,如果數據在一段時間內有插入,又有刪除,那麼你得仔細的調整這棵樹使其永遠保持平衡。實際上, 每次的插入和刪除動作都是對這組數據的一次重新排序,平衡二叉樹能做到對這種重新排序操作的算法複雜度也在O(logn)。 從這個意義上說“平衡”具有更加深遠的意義,即所有訪問路徑上的性能平衡,這使它成爲實現關係型數據庫最實用、最基礎的數據結構。

進一步思考平衡二叉樹,你會得出一個有趣的結論:平衡二叉樹是一個層級結構,它的物理實現也是個導航型數據庫。 一個更加抽象化的物理模型也就具有更廣泛的通用性。導航型數據庫相對於平衡二叉樹正如層級數據模型之對於關係型模型。

回到一開始的問題,實現關係型模型到底有多難?答案是:非常難。我們舉得平衡二叉樹的例子也許並沒有讓你生畏, 那只是因爲我們遺漏了太多的工程細節,例如:範圍查詢如何實現,節點動態分裂,索引同步更新,併發控制,等等。 然而我們已經知道要實現對稱探索,並且保證一定的性能,我們需對涉及查詢的多個Domain建立索引。如果不那麼做, 你就無法避免全表掃描帶來的資源侵吞;而如果你這麼做了,你在插入和刪除數據的時候又得兼顧對這些索引的同步更新,以保持數據的一致性。

每個索引本質上就是一個導航型數據庫,索引的自由建立意味着關係型數據庫要成爲導航型數據庫一個高層次的抽象, 它要負責協調多個導航型數據庫的一致性。在上世紀70年代初,在硬件剛好能承受導航型數據庫的年代裏,這種設想僅僅是一種美好的願景。 然而摩爾定律最終讓這一切成爲現實,10年後,硬件的性能終於能夠承載起關係型數據庫。從某種意義上說,ORACLE可能當時正好撞上了風口。

關係模型之上是否還可以再抽象?這是個有趣的問題,我不知道數學之上是否還可以抽象,如果數學已經是這個世界最高層次的抽象, 那麼關係模型也就無法再抽象了。事實也證明在關係模型之後,出現的許多數據庫模型反而都是關係模型的具象化, 這其中最爲著名的便是實體-關係數據模型。

實體-關係數據模型

在Codd提出關係模型的6年後,另一篇論文對關係型數據庫的發展起到了非常重要作用。這便是由陳品山博士在1976年發表的論文: “The Entity-Relationship Model”。

實體-關係數據模型(E-R模型)爲設計數據庫提供了一種更爲直觀的描述。如果說Codd的靈感來源於數學,那麼品山的靈感一定來源於自然語言。 事實上,品山自己也提到過中文對其思維方式的影響。因此,我們不妨將E-R模型和自然語言作一個類比。

自然語言 E-R模型對象
普通名詞 Entity Type
專有名詞 Entity
及物動詞 Relationship Type
形容詞 Attribute for Entity
副詞 Attribute for Relationship

圖7.E-R圖

圖7是一個E-R圖的例子,描述一個現實中的商業行爲:上海的客戶A購買了3個商品B。客戶和商品是Entity Type(用方框表示), 客戶A和商品B分別是其對應的Entity; 如果通過客戶名能唯一確定一個客戶,那麼客戶名是主屬性(橢圓加下劃線),地址爲一般屬性(橢圓); 客戶和商品通過“購買”這個行爲聯繫在一起,“購買”是Relationship Type(用菱形表示),一般情況同樣的商品可以銷售給不同的客戶, 同一個客戶也可以購買不同的商品,因此這裏是個多對多(m:n)的Relationship;“數量”是Relationship的一個屬性,用於描述此次購買行爲。

E-R模型非常的直觀,並且易於理解,這源於它和自然語言良好的兼容性。將E-R模型轉換成關係型模型也很直接, 你只要將Entity和Relationship分別對應到一個Relation就可以了,於是便有Entity Relation和Relationship Relation, 而且能很自然的達到3範式,這個在關係模型中需要通過規範化操作(Normalization)去實現。

       客戶(客戶名,地址)
       商品(商品名)
       購買(客戶名商品名,數量)
    
 Relation和Relationship有什麼區別?這個問題從數學角度更容易理解: Relation對Domain是有順序要求的, (a, b, c)與(b, a, c)是不一樣的;而Relationship沒有這方面的要求。 E-R模型中的Relationship是指n個Entity之間的關係(n>=1),而對Entity沒有作順序要求。

實體-關係數據模型更多的是以E-R圖爲世人所熟悉。一方面對於業務人員來說,它非常直觀便於掌握;另一方面,它能很容易的對應到關係型模型, 因此也無須爲它再單獨設計一個物理模型。E-R模型就這樣介於概念模型和邏輯模型之間。實際上,長期以來人們已經將E-R模型等價於概念模型, 或者更確切的說是關係型數據庫的概念模型。

然而當開發人員將E-R模型轉換成關係模型的時候,有時候很難區分Entity Relation和Relationship Relation。 這也可以從自然語言中名詞變動詞,或者動詞變名詞等生動活躍的語法中體現,這時候準確理解它們需要結合一定的語境。例如:在圖7中, 如果你只將“購買”理解成一種行爲顯然是不夠的(不貼合商業語境),一般情況下,會將“購買”這個Relationship Type具象成一個邏輯的Entity——銷售訂單,這樣就符合商業語境了(參見圖8)。這裏的原因在於商業組織本身就是一個信息系統(即使在沒有計算機系統之前),它已經經過一層信息化的抽象,形成了其固有的溝通語境。 它並不完全等同於自然語言溝通系統,因此在很多情況下直接比對到關係模型反而更加簡單。


圖8.現實中銷售活動的E-R圖

仔細觀察上圖中用E-R圖描繪的一個典型銷售活動,並嘗試用我們的自然語言去闡述它。你也許會驚訝的發現E-R模型和自然語言共享着一些本源性的東西。 我們的自然語言本身就是對現實世界的一種模型化,這種本源性的東西一直紮根在人類的思維中,並指導着人類認識這個世界。 如果有可能讓E-R模型變成一個邏輯模型,進而擁有自己的物理模型實現,那麼我們是否可以讓計算機變得更像人腦? 現代的物理學向我們證明宇宙是建立在數學之上的,然而宇宙中產生的智慧又是反應數學的一個最生動的具象。 E-R模型通過將關係模型印射到自然語言降低了其通用性,然而這是否能讓以E-R模型爲邏輯模型的數據庫在特定領域發揮出更好的優勢呢? MDB最初就是基於上述的想法和衝動去搭建的,關於這部分內容我們會在後續的博客中單獨介紹。

後續的發展

接下來數據庫模型的發展可簡單歸結爲2個方向:其一是繼續沿着具象化的道路前進;其二則是針對特定應用領域的性能優化。

具象化方向

在這個方向上,最有影響力的便是對象模型(Object Model)。對象模型是伴隨着面向對象的編程(Object-Oriented Programming)一起被提出的, 然而在實際應用過程中,對象模型並沒有像OO-Programming那樣風靡。這是可以想象的,對象模型相對於關係模型的進一步具象化使得“對稱探索”變得不可能。 對象模型更多的是給程序員帶來了方便,這樣他們可以有效減少大量管道代碼(那些用於將數據格式轉換成關係模型的代碼),但在其他方面看不出它除了限制外還能帶來什麼。 在後續的發展過程中,對象模型的影響力主要體現在對SQL語言的對象化擴展以及衆多的ORM(Object-Relational Mappings)框架, 但卻絲毫沒有撼動關係模型和關係型數據庫的地位。

性能優化方向

性能是數據庫發展的第一推動力。在過去30多年裏,摩爾定律一直是性能最有力的保障, 然而互聯網時代的海量數據以及幾何級的增長速度使得摩爾定律帶來的性能紅利猶如杯水車薪,更何況摩爾定律似乎也到了強弩之末。 這讓關係模型再次受限於硬件,然而我們似乎已經掌握了應對之策——分佈式模型,這也是迄今爲止對關係型數據庫最大的一次衝擊。 我們會在這個系列的第四篇博客中詳細介紹分佈式數據庫模型,在這之前,我們先關注另一個曾經在性能方向引起波動的數據模型, 這便是下一篇博客中的內容——《OLAP浪潮》。

附錄:數據庫發展時間線

圖9. 數據庫發展時間線
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章