最近看到一篇關於NoSQL資料庫的報導,勾起了一些回憶,不過,在談這些前,先讓我們簡單介紹一下何謂NoSQL資料庫。

從名稱可以很容易理解NoSQL資料庫究竟是什麼,基本上,打從名字開始,它就告訴你,它不是利用典型SQL語法存取資料的資料庫。一般來說,「NoSQL」資料庫泛指非關聯式的資料庫。

關聯式資料庫的崛起與普及
對很多程式設計者而言,所謂的「資料庫」,指的便是「關聯式資料庫」,而存取資料庫的方式,則是透過所謂的SQL語法,寫下SQL述句來儲存、或者查詢所需的資料。大約在1970年代人們就開始發展關聯式資料庫的技術,也開始有第一套關聯式資料庫商業系統問世。從1970年代發展至今,關聯式資料庫的技術可以說是發展到十分的成熟,成熟到大多數存取資料量稍有規模的應用系統,多半都會使用關聯式資料庫來存取資料。可別以為,只有伺服器端的系統才會使用關聯式資料庫喔,最近微軟所推出的Visual Studio 2010,其中的Visual C++用來記錄一些經剖析後得到的原始碼結構資訊,便也是利用微軟自家的Microsoft SQL Server Desktop Engine來記錄。現在,連供程式設計者開發應用程式的IDE(Integrated Development Environment),最終都走上了使用關聯資料庫來記錄所需的資料。由此便可見,關聯式資料庫的應用究竟有多普及、廣泛了。

關聯式資料庫對軟體系統開發而言,能夠扮演如此重要的地位,有一個很重要的原因,便是它提供了一個既高階、且抽象的資料存取模型,也就是目前大多數人所認識的關聯式資料表的概念。除此之外,SQL語法也在這模型之上,提供了一個一般化的存取方式。對於系統的開發者而言,可以不需要理會資料究竟實際上會被如何儲存、也不需要了解所需要的資料究竟是怎麼被檢索出來的,他們只需要知道如何透過SQL語法來儲存、查詢資料即可。由於SQL語法是如此的高階且容易入門(卻也是易學難精),使得一切資料庫實作細節可被隱藏不為程式設計者所知,大多也無礙他們於資料的存取。而現代關聯式資料庫是如此的高效、計算機器是如此的快速,使得即使程式設計者僅透過高階的SQL語法,也仍能以不錯的效能來操作系統所需的各種資料。

這麼便利又好用的東西,叫程式設計者如何不能上癮,漸漸增加對它的依賴呢?

正如我在前段所說的,在現今,大多數存取資料量稍有規模的應用系統,多半都會使用關聯式資料庫來存取資料。其中的差別只是在於所選用的資料庫不同罷了!姑且不論那些大型、完善且複雜的關聯式資料庫,有時,如果你只是想要一個小型、輕量化的關聯式資料庫,你還有像SQLLite這樣的解決方案可供選用。這種管理資料的方式,不僅僅只是大行其道,甚至還差不多快成為唯一的方式了。

因為便利而使人越來越依賴既有的技術,甚至忘記可以自己重新開發
人類文明的進化似乎都有一個共通的模式──當在某方面得到進化後,往往便意謂著某方便朝向退化。例如,當機動的交通工具被發明之後,人類的步行能力就開始退化了。從這一點來看,程式設計者在處理資料儲存這件事上也不例外。

時光倒回到十多年前,那時臺灣正開始流行所謂電子布告欄系統(BBS)。身為程式設計者,除了使用BBS之外,由於當時的BBS系統多採開放原始碼,因此,難免也會研究一下BBS程式的寫法,並藉此練功,觀摩高手的手法。那時的BBS,除了利用大名鼎鼎的Berkeley DB,來儲存系統所需的資料。當然,Berkeley DB並不利用SQL做為資料查詢的語言,它僅能儲存那些成對的鍵、值資料。

除了Berkeley DB之外,一些BBS系統也會設計自己儲存資料的資料結構及格式,而這些資料結構及格式,完全是針對它們特定的應用需求而量身打造的。也就是說,若設計得夠好,不會有額外超乎需求的空間、也不會為了兼顧一般性,而浪費效率。

在那個時候,我還沒有經歷過關聯式資料庫的洗禮,沒有沉浸在它那無上便利威力的經驗,從這些BBS系統設計者的作品中,卻學到了一件重要的事──要懂得設計自己所需的資料儲存結構,在必要的時候。

自那之後的幾年,只要是自己設計的系統,在需要儲存資料的場所,我幾乎都會自己設計儲存的結構及格式。那時,在開發一個網路硬碟的系統時,甚至自己仿inode的觀念設計了一個檔案系統,用來儲存網路硬碟中的檔案及目錄結構。

後來,工作型態有了很大的轉變,突然間跳進去商業系統的開發領域。在之前的經驗,在開發系統的第一步,往往就是先分析出它的資料存取需求,接著設計、實作出專屬的資料儲存核心。然而,身邊的人突然都不這麼做了,他們用關聯式資料庫系統來儲存資料、利用SQL來存取資料。一時之間,所接觸、所用的全都是關聯式資料庫、SQL。

這麼棒的東西,既然都用了,又怎麼不依賴呢?

某種程度來說,我是進化了。關聯式資料庫及SQL,本來就是高度一般化的產物,其機制及設計,兼顧了絕大多數資料儲存時的需求,同時取得一個極佳的平衡點。適當的加以應用,絕對可以大幅節省開發的時間,同時維持儲存系統的穩定及資料的可靠度。只是,時間一久,在長期習慣了這種便利性之後,向來喜歡自己造輪的我,竟也淡忘了過去自己設計資料儲存方案的習性。

標準平臺有其局限,必要時,仍須自行開發專屬的解決方案
有一回總算踢到了鐵板。某一個系統需要處理的某一種資料量實在太大了,規模成長大到我們所使用的關聯式資料庫系統負荷不了,資料無論是儲存或者是查詢的速度,都十分緩慢。倘若要再繼續使用關聯式資料庫來處理這資料,除非換上更高效的資料庫系統,同時更新相關硬體設備,否則,勢必是無法解決的。

正當為此而發愁時,腦中靈光一現,想到了舊日謀生的技藝,於是趕緊分析一下這個吃資料庫像吃水一樣的怪獸,其資料儲存的需求究竟為何,可以使用什麼樣的資料儲存結構來替代目前儲存在關聯式資料庫中的方式。
簡單來說,便是以特殊化的實作來取代一般化的方式,為這種資料設計出專屬的存取結構。事實上,這種資料其量雖大,但存取方式十分單純,所以,反而使用簡單的一套機制,便可以處理大量的資料,而且效率還很高。如此一來,總算解了燃眉之急。

這次的經驗讓我警覺到,諸多便利的開發工具及系統協助,就和自動化的交通工具一樣,固然能夠在大多數情況下大大的提升效率,但是,總會有一些場合,是這些工具應付不來的。這正如風光秀麗的絕景,多半是汽車無法行駛之處。

身為一名程式設計者,在一般化的場合,運用可提升效率的工具或平臺,對生產力大有助益,這也是文明進化的必然結果。

只是,對於那些特殊的應用情境,千萬別忘了,程式設計者永遠需要有能力去做到一件事,那就是,憑藉自己力量調整出更適用的設計。否則進化的同時,也帶來了退化。

專欄作者

熱門新聞

Advertisement