在通常的數據庫設計中,我們定義了每個實體有多少個屬性,每個屬性的數據類型是什么,有多長,是否允許為空,有什么約束條件等,這些定義是完全靜態的,系統創建時就全部定義好,不能動態修改。但是對於實體的屬性變化很快,或者實體和屬性由用戶在系統中自行定義的情況下,那么就需要一個可以動態擴展的數據庫模型,以保存各種動態產生的數據。
比如我們要做一個電子商務網站,需要建立一個商品表以保存各種要賣出的商品的屬性。但是商品的屬性各種各樣,不同類別的商品在屬性上千差萬別,不可能建立一個靜態的商品表來存儲所有的屬性。這個時候就需要建立動態的數據庫模型。
常見的動態擴展的數據庫設計方法有以下幾種:
一、以字符串存儲各種數據類型,通過行轉列實現實體屬性讀取。
以前提到的電子商務網站的商品實體為例,我們可以建立兩個表“商品”和“商品屬性”,商品表為普通的商品屬性,可以將商品名稱、價格等大部分商品的公共屬性放到該表中。商品表與商品屬性表形成一對多關系,商品屬性表只需要定義商品“屬性名”和“屬性值”這兩個屬性用於保存一個商品的各個屬性。
這樣在每讀取一個商品時,可以讀取該商品的屬性集合,然后將屬性集合重新綁定到對象,將該對象暫時在頁面上。
這種做法的優點是靈活,可以為商品創建無數個不同的屬性,可以應對電商這種快速變化,快速上線的需求。缺點是后期做統計的時候會很慢,因為需要行轉列,如果要涉及到各種Join查詢之類的也會很麻煩。
二、預定義大量的冗余列,根據用戶對實體屬性的類型設置匹配對應的列。
如果我們不希望行轉列的話,那么可以預先定義好數據列,由於不確定是哪種數據類型,所以我們可以將表的列定義的特別多,每個不同的數據類型都定義幾個或者十來個列,這些列都是允許為空的,如果沒有使用已經預定義好的列,並不會占據多少數據空間。
在SharePoint 2007或者更早的版本中,對列表的數據存儲就是采用這種方式,以下是SharePoint2007中的AllUserData表的結構。基本上為每種數據類型定義了十來個到幾十個的列,用戶在創建不同的列表時,都可以使用這個表存儲列表數據。
這種數據庫設計方法的優點是不會存在行轉列的問題,所以在join或者出報表時性能較好,缺點就是使得一個表的列特別多,而且大部分列在大多數情況下是不使用的,而且擴展比較困難,比如我們要定義17個bit類型的列,但是系統默認只有16個,這種情況下,就需要在數據庫中使用2行數據來表示1行列表數據。
三、使用XML數據類型存儲動態列數據。
XML數據類型是SQL的一個標准,目前主流的數據庫都支持XML數據類型,數據庫為XML提供專門的語法以快速檢索和操作XML數據。在新版的SharePoint中,就使用XML來存儲用戶自定義列表的內容。
對於前面提到的商品表和商品屬性表,其實也可以只建立商品表,在該表中添加一XML類型的列,用於存儲商品的各種屬性。這是比較推薦的一種處理方法。
四、為用戶定義的實體動態創建表。
還有一直動態方法是在程序中動態創建表,用戶每在程序中定義一個實體的時候,就好根據用戶定義創建一個對應的表。比如微軟的Dynamic CRM就是這樣實現的。用戶可以在系統中創建大量的實體,並且還可以定義實體之間的關系,系統就會按照用戶的定義創建對應的表,以及外鍵。
這種方法的優點是性能好,每個實體與其數據庫表相對應,不存在大量的冗余列,也不會存在行轉列的問題。缺點是開發難度大,對用戶的要求高;而且在創建好實體並且存儲了大量數據后,如果想要修改實體屬性,那么將很困難。