宅男程序員給老婆的計算機課程之9:數(shù)據(jù)模型
原創(chuàng)這次來講MVC中***的M。
Model,幾乎可以說是網(wǎng)頁應(yīng)用的核心。
之前課程提到過網(wǎng)頁應(yīng)用是由數(shù)據(jù)庫驅(qū)動,而在很多場景,數(shù)據(jù)庫 = M ; M = 數(shù)據(jù)庫。
所謂的ORM; object relational mapping。
現(xiàn)在新的網(wǎng)頁開發(fā)框架,特別是MVC框架,都會提供ORM支持,避免程序員直接寫SQL、操作數(shù)據(jù)庫。
傳統(tǒng)上,ASP/ php臭名昭著的sql注入問題,便是因為菜鳥程序員直接在程序中根據(jù)用戶輸入拼接數(shù)據(jù)庫造成的;而使用ORM框架,則可以徹底避免這種問題。
ORM有兩種風(fēng)格,一種是 R => O;一種是 O => R 。
====== R => O ======
傳統(tǒng)上,程序員也都是先完成數(shù)據(jù)庫設(shè)計(甚至是由DBA完成),然后再考慮相應(yīng)的對象生成,也就是所謂的 R => O。
在這樣的場景下,整個軟件的框架,還是以數(shù)據(jù)庫為核心,業(yè)務(wù)的設(shè)計思維是以關(guān)系型數(shù)據(jù)庫的表結(jié)構(gòu)為基礎(chǔ)去考慮的,具體應(yīng)用實現(xiàn)上,會考慮很多關(guān)系型數(shù)據(jù)庫的功能特性,比方說,外鍵,joining等等,并且,程序員需要直接考慮“數(shù)據(jù)庫設(shè)計三范式”,以及冗余字段等面向數(shù)據(jù)庫的優(yōu)化手段。
并且,程序員也很可能會采用數(shù)據(jù)庫的一些高級特性,如視圖、存儲過程、甚至觸發(fā)器等等以方便使用。
O的存在,僅僅是為了方便操作數(shù)據(jù)庫表。
====== O => R ======
這種設(shè)計哲學(xué)則是相反,程序員做業(yè)務(wù)分析、實現(xiàn)架構(gòu)設(shè)計的時候,并不過多考慮數(shù)據(jù)庫的特性與限制;程序僅考慮自己的業(yè)務(wù)對象:編程語言中的對象。
數(shù)據(jù)庫僅僅只是作為一個對象持久層來考慮:
* 程序運行的時候,對象是自動保持在內(nèi)存中。
* 但在對象狀態(tài)改變、程序退出的時候,將對象保存進數(shù)據(jù)庫。
* 程序重新啟動的時候,則從數(shù)據(jù)庫中獲得原先數(shù)據(jù),并還原為內(nèi)存中的對象。
在這樣的場景下,數(shù)據(jù)庫是一個可以被替換的存儲層,它可以是關(guān)系型數(shù)據(jù)庫,也可以是NoSQL,甚至是硬盤文件;所以,即便使用關(guān)系型數(shù)據(jù)庫,一般也不會使用其高級功能。
設(shè)計哲學(xué)的不同直接造成了使用技術(shù)的不同。
====== 比較 ======
在ED開發(fā)圣經(jīng)PEAA中,列舉了下面三種方案:
1. Trascation Script
也就是直接拼接SQL啦~
2. Table Module
R => O;并且,O非常簡單,直接以類似數(shù)組的方式讀取表數(shù)據(jù)。
.net中ADO.net的DataTable / DataRow對象便是這種設(shè)計的典型實現(xiàn)。
3. Domain Model
O => R,直接設(shè)計業(yè)務(wù)領(lǐng)域(Domain)的對象,然后在考慮對象的持久化方案。
針對上面3中方案,Martin Fowler畫了下面這張著名圖解:
http://www.hamishgraham.net/page/Work-Habits.aspx/Architecture/Business-Layer
他的結(jié)論是:
使用Table Module的方式,永遠比直接寫SQL簡單;在簡單的業(yè)務(wù)場景下,Table Module也會比Domain Model簡單,但Table Module的方案復(fù)雜度會隨著業(yè)務(wù)復(fù)雜化而快速增長。
反之,Domain Model的復(fù)雜度跟業(yè)務(wù)復(fù)雜度相比始終保持水平增長;它雖然一開始最復(fù)雜,但隨著業(yè)務(wù)復(fù)雜度超過一定程度后,它反而會成為最簡單的方案。
就我自己的開發(fā)經(jīng)驗,基本與Fowler的描述吻合;但隨著ORM技術(shù)的成熟,Domain Model,未必如他在圖中畫的那樣,一開始就有那么高的復(fù)雜度。
關(guān)鍵是看程序員是否習(xí)慣于關(guān)系型數(shù)據(jù)庫的實現(xiàn)方案,如果是,那么,切換去Domain Model,確實會比較麻煩,各種不適應(yīng)。
但如果是一個沒有關(guān)系型數(shù)據(jù)庫經(jīng)驗的程序員,或者說,沒有強制使用SQL思維習(xí)慣的程序員,使用Domain Model,也可以是很自然的方案。
下一課,講繼續(xù)詳細說明Domain Model。
作業(yè):
1. ED開發(fā)圣經(jīng)PEAA究竟是哪本書?
2. 數(shù)據(jù)庫三范式是什么?
3. 關(guān)于Domain Model,什么是充血模型?什么是貧血模型?
51CTO系列: