首先是一些廢話:
前文鏈接:
在《我們該如何設計數據庫(二)》中,園友Jacklondon Chen提出了一些問題,大致如下:
“man/woman應該設計在同一張表中。 用戶表大多都設計成一個表。連分 administrator 和 user 都不應該。”
我想還是因為我舉例太隨意,因為博文中Man和Woman只有4個差異屬性:HasCar\HasHouse\HasMoney,以及IsBeauty
其實對於這個問題我無力吐槽什么,簡單的說說吧:假設為Man用戶實現的是一個征婚系統,而Woman用戶實現的是一個選美系統。這么說應該能理解Man和Woman的不能並同一張表的原因了吧
廢話說完,正文開始
/*=============================================================*/
現在有一個系統,我們暫時假設為學校選課系統。有兩類用戶Teacher和Student,還有一張Curriculum表是課程總表,來儲存學校一共有哪些課程,每門課的學分什么的。然后一個老師,一門課程和多名學生,就可以開始上課了
表結構如下圖:
邏輯很簡單,一目了然
但是問題在於,我們的系統要按學校來賣。每個學校的選課邏輯都是一樣的,而表中的數據有共性,但是也有差異性。比如說基本的Teacher表結構是這樣的:
現在把系統賣給A學校。A學校除了的Teacher表除了用戶名和密碼之外,還要儲存老師的FirstName和LastName,那么表結構變化如下:
現在B學校也買了我們的系統。他們的Teacher表不要FirstName和LastName,但是要儲存教師的工號“Number”,表結構如下:
好,現在我們的問題出來了:怎么去解決這種差異性
最簡單的思路莫過於表中加冗余字段。比如說將表設計成這樣:
如果我們的系統只賣兩三個學校,這樣是可行的。但是打個比方,我們的系統賣了30所學校,每個學校有一個自己的差異字段,那么這個表就要有30個冗余字段來應對這種差異性。且不說每次加冗余都要改動系統,且不說冗余多了浪費空間降低傳輸效率,光說怎么維護這些冗余,我就已經覺得是災難了:Teacher表有差異字段,其他表也會有。假設一個中型系統,60張表,其中30張實體表30張關系表不算過分吧。那么總共要維護 30(表數量)*30(冗余數量) = 900 個差異字段
第二個想法是建立一張冗余表來儲存差異。這種其實和表中加冗余異曲同工,就不多加分析了,留給大家自己思考
第三個想法是建立不同的數據庫。其實本來每個學校的數據庫就是不同的,唔……怎么說呢,A學校自己的數據庫中的表,存的是A學校自己的特有字段,B學校存B學校的特有字段。兩者之間並無關系,然后Model用l繼承的思路來設計(詳見上一篇文章),通過配置文件來選擇恰當的數據庫和其對應的Model
是的,這種方法挺好的,唯一的不足可能就是比較依賴於ORM——使用ORM來生成數據庫,以及T-SQL語句
如果您是一個關系型數據庫的重度愛好者,那么這篇文章到這就結束了,下面的東西不會對您胃口的
/*=============================================================*/
眾所周知,因為大量使用了反射,ORM的效率不是那么的高,而且本身關系型數據庫的可拓展性也不是那么的好
作為一個激進的開發者,我一直希望在項目中嘗試NoSql
下面的一篇文章我會講解如何用MongoDB來解決前文描述的差異性問題,敬請期待
關於MongoDB的入門,推薦兩篇文章:
MongoDB實戰開發 【零基礎學習,附完整Asp.net示例】
順便附上一個小測試:在.net 4環境下分別插入5W條數據,分別是EF5、Nhibernate、ADO.Net向Sql server 2008插入,以及MongoDB官方驅動向MongoDB插入
EF耗時:00:00:25.4972758
ADO.NET耗時:00:00:23.8307860
NHibernate耗時:00:00:26.0199898
MongoDB耗時:00:00:01.9474134
在這里,EF每次插入1000條數據(批量插入),其他方式都是單條插入;NHibernate關閉了一級緩存;
MongoDB使用的是“離弦之箭”的插入方式
MongoDB使用的是安全的插入模式(不會丟失數據)
/*=============================================================*/
PS:在閃存里面說在博文中自曝照片的,不過因為這篇文章是在公司寫的,就等下一篇再說吧
再PS:馬上10·1了喲吼吼吼