2009年1月22日 星期四

為Database-Centric Architecture平反 Part 1

對軟體服務業而言,這四十年來資訊技術最重要的發明是什麼?

我的答案是『物件導向技術』以及『關聯式資料庫』這兩項。

我一直是物件技術的擁護者。工作上常常宣揚Design Patterns和Analysis Patterns的重要,喜歡把老舊的程式Refactor翻修成物件的架構。做SA時頭腦中的模型都是繼承、多型與patterns。何況Agile Methodology要透過物件技術才能發揮得淋漓盡致。

另一方面,可能是因為純數學背景的關係,我也很喜歡關聯式資料庫。SQL語法基本上就是充滿了集合論的風格(select from多個table就是做Cartesion Product,where條件就是由Axiom Schema of Separation定義集合的property,還有union, intersection等集合運算)。剛進這一行,SQL就用得很順手,因為它應用到求學時接受的純數學訓練。


回顧關聯式資料庫的特異功能
關聯式資料庫(RDB),是把幾十年來發展出資料結構與演算法技術(如我們熟知的搜尋、排序、Hash、merge等等),封包成一個有高度智慧的引擎。用很高階,接近自然語言的SQL來操作這個引擎。RDB會即時編譯並優化SQL,找出最佳的演算法來執行。在資料庫技術成熟前,資料的儲存維護與查詢是需要自己實做的。所以早期的程式設計師門檻很高,需要自行開發,應用這些演算法與資料結構來處理大量的資料。以排序為例,我們在演算法的課學到的quick sort之類的各種方法其實還不夠,因為應付大量資料時,不能只在記憶體中作業,常常要在儲存媒體(硬碟)上作業(external sort)。善用有限的記憶體空間,找出最有效率的媒體存取的順序,當然比純粹在記憶體中排序要複雜得多。今天我們不需要自己寫程式處理在硬碟上兩億筆資料如何搜尋最有效率,只需下個select命令,資料庫自動幫你找出最有效率的作法來執行。平時資料的新增與異動,資料庫也會即時更新索引與統計,安排儲存空間配置等等動作。想想看,這是多了不起的成就!

現代的資料庫系統還能控制transaction:一連串的動作都成功,整個交易才生效,不然就roll back回到先前的狀態。也會控制concurrency:多人同時存取同樣的資料時,會做適當的鎖定,避免資料錯亂。很難想像不借助資料庫,自己寫程式的話如何照顧到那麼多層面的問題。

資料模型+UI糖衣=系統成品
ER模型(Entity-relationship model)及其他類似的資料模型方法,是跟隨RDB概念而發展出來的一種SA方法。找出資料間的關聯。一對多、多對多、主鍵等,釐清之後整個商業邏輯的外觀就浮現出來了。

和物件模型相比,ER模型有個很大的優勢,這個優勢常被開發者忽視。就是

『ER模型』跟『系統成品』只有一步之遙。

ER模型產生以後,可以直接用DB管理工具將這個模型建成資料表與關聯(要填補的細節只是欄位格式,如char或varchar, allow null, autoincrement之類的),DB會立即將建立的規則編譯建置成為這個系統的核心。建完表單後,某種角度而言,系統就已經開發好了。因為接下來所有的交易與查詢都可透過SQL指令完成。

當然,為了重複的動作一直下相同的SQL很不方便。SQL一旦不慎下錯可能造成資料嚴重的損失。更重要的是使用者通常不使用SQL。所以我們要再包一層圖形介面的糖衣(或者再加一些不容易在資料庫做的資料正確性檢查),讓常用的作業容易操作。介面程式將使用者輸入的動作轉變為SQL。這樣以資料庫做為系統主體的架構,稱為Database-Centric Architecture。

我承認,『資訊系統在資料庫,GUI只是便利操作的糖衣。』這個概念,不是永遠都能實現的。有時複雜的商業邏輯不容易定義在資料庫端。請先忍耐一下,很快會再回到這個問題,做更深入的探討。

物件模型雖強大,但後續實做的工程也較大
和物件模型做個比較。以 SA方法而言,物件模型比資料模型要強大多了。物件模型除了有等同於ER的關係以外,加上了封包、繼承與多型等技巧。能簡化複雜邏輯的能力真是不可同日而語。不過,物件模型做出的SA,距離成品很遙遠。例如Quantity class(請參考Quantity Pattern)。用XML表現只需要一個單一class的class diagram:
但是實做這個class,不含GUI,也得花上半天至一兩天的功夫。不像ER模型那樣可以直接在管理工具上拉出成品。Kent Beck的名著Test-Driven Development by Examples,整本書中就有半本是在實做Quantity的特例:Money class。

資料處理 vs. 商業邏輯
以資料庫為系統中心的架構主導了市場很久。但是如同剛剛所提到,有的商業邏輯不適合集中在資料庫,而必須做在UI上。甚至於發展到後來,UI上的邏輯也有可能太複雜,於是有3-tier架構的產生,邏輯被移到中間層。那今天這個3-tier與物件技術盛行的時代,Database Centric架構該被淘汰了嗎?或者說,什麼樣的系統,才適合Databese-Centric架構呢?

當我們資訊人員說『商業邏輯』,是指『要讓資訊系統處理的商業邏輯』。但是有更多實質上的商業邏輯是由人工作業來處理的。這種情況下我們只希望系統忠實地紀錄資訊,我們需要處理時,系統只要將相關資料用對我們方便閱讀的格式呈現出來就夠了。隨著開發技術的進步,可能讓電腦處理的商業邏輯越來越多,也越來越深。但是今天大多數的商業邏輯還是需要人工來處理,而電腦系統的商業邏輯不一定都很複雜。

我的看法是,
當資料欄位大多與系統的商業邏輯無關,系統只負責資料的保存與呈現時,就適合用Database-Centric架構。
不要低估這個條件的適用性。我們最常用的軟體系統大多符合這個條件。例如討論區、Blog、Wiki等。

看你的記事本,上面紀錄了各種想法、和客戶討論的結論、重要約會與工作時程。對日常工作而言,這些都是重要資訊。但是從記事本的角度而言,它不知道我們在上面記了什麼,不詮釋任何商業邏輯,不做任何處理,它的工作只是保存資訊,讓我們方便翻閱。但是記事本是非常實用的。

也許記事本不是軟體,這個類比不夠生動,另外舉email為例。email內容往往涵蓋重要的商業訊息:工作指派與回報、規格確認、會議邀請等等。但是email軟體上沒有人工智慧可以收到主管派工就自動加一項工作在行事曆待辦事項,也不會收到客戶的確認就自動更新需求確認書,也不懂得在會議時間跟其他行程衝突就自動回絕。但是email仍是我們最重要的工具之一。

雖然OO架構的彈性與擴充性都更大,對很多人(包含我)的品味而言也優雅許多。但是放棄Database-Centric架構就多少犧牲了前述的兩大優點。這意謂著:1.需要撰寫的程式碼較多,以及2.資料量大時容易忽略效能問題。決定架構之前最好先評估OO架構的便利性,是否真的大到足以抵銷到這兩個損失?這要看專案的特性:需求、時程、預算、未來擴充的可能等因素。

2 則留言:

喵尾巴 提到...

有趣的議題,點出了OR Mapping 的帶來的問題(當然它也解決了許多的問題)
就算有了像Hibernate 這般的利器,優美的物件模型仍然無法完全悠遊於資料庫之上。中間的Overhead 怎麼平衡需要客觀思考

EC 提到...

的確這是一個讓我頭痛的思考,也有其他讀者反映類似的問題。怎麼平衡?或者是,能不能平衡?

思考如何平衡之前,還有些頭痛的問題:

1. 兩種技術容不容易並存在一個系統中?
2. 已經用了DB Centric開發的code 好不好轉換到OO架構?

這兩個答案如果都是肯定的,那我們就有辦法研究兩者間如何平衡.否則,好像很難求取平能:只能二選一。

Part 3我會試著討論這個議題。