2013-09-16 65 views
6

我已經使用了面向行的數據庫設計很長一段時間,除了datawarehouse項目和大數據示例,我還沒有使用OLTP應用程序的面向列的數據庫設計。面向列的數據庫vs面向行的數據庫

我行面向表看起來像

ID, Make, Model, Month, Miles, Cost 
1 BMW Z3  12  12000 100 

有些人在我們的團隊崇尚面向列的數據庫設計。 他們建議所有的列名稱應該是屬性表中的屬性名稱。 然後另一個表格引用將有兩列PropertyName和PropertyValue。

在.net代碼中,我們讀取每個鍵並比較並轉換爲強類型對象。代碼真的很亂。

if (qwi.DomainCode == typeof(CoreBO.Base.iQQConstants.MBPCollateralInfo).Name) 
    { 
     if (qwi.RefCode == iQQConstants.MBPCollateralInfo.ENGINETYPE) 
     { 
      Aspiration = qwi.Value; 
     } 
     else if (qwi.RefCode == iQQConstants.MBPCollateralInfo.FUELTYPE) 
     { 
      FuelType = qwi.Value; 
     } 
     else if (qwi.RefCode == iQQConstants.MBPCollateralInfo.MAKE) 
     { 
      Make = qwi.Value; 
     } 
     else if (qwi.RefCode == iQQConstants.MBPCollateralInfo.MILEAGE) 
     { 
      int reading = 0; 
      bool success = int.TryParse(qwi.Value, out reading); 
      if (success) 
      { 
       OdometerReading = reading; 
      } 
} 
} 

此面向柱設計arguement是,我們不會有改變表模式和存儲過程(我們仍然使用存儲過程,而不是實體框架)。

好像我們正在進入真正的問題。行業導向設計是否被業界所接受。

+1

這個問題似乎與「面向列」(列存儲)的DBMS無關。問題實際上是關於EAV設計模式。 – sqlvogel

+0

「我們仍然使用存儲過程而不是實體框架」 我在許多較小和中等規模的項目中使用EF,並且不再認爲EF是一種可行的方式。 從我測試和理解的情況來看,EF需要讓內存中的數據能夠操縱它(即更新),這是一個考慮到嚴肅工作時常常是門擋的情況。 – Mariusz

+0

「我們仍然使用存儲的proc而不是實體框架」 EF似乎需要內存中的數據才能修改它,所以這樣簡單: UPDATE dbo.MyTable SET Active = 1 WHERE Active = 0 對於大量的數據可能不是微不足道的使用EF(但我也喜歡它,因爲它踢了屁股大的時間) – Mariusz

回答

10

我遇到了術語問題。您正在描述一個EAV結構(代表實體屬性值)。另外:「面向列的」數據庫通常是指將數據庫中的每列與其他數據庫分開存儲的數據庫(當我瞭解數據庫時,這被稱爲「垂直分區」,但我不認爲這種情況已經發生) 。例子包括Paracel和Vertica。

實體屬性值數據庫將實體的每個屬性存儲爲單獨的行。

您在特定結構中遇到的第一個問題是鍵入。一些屬性是字符串,一些是數字。這成爲EAV世界的管理噩夢。您可以將所有內容都存儲爲字符串(無法輸入檢查值並保證算術單詞),也可以爲不同類型的多列添加類型列(使查詢更加複雜)。

類似地,約束和外鍵引用實現起來要困難得多。另外,由於您在每行重複實體ID和屬性ID,因此數據通常會佔用更多空間。 NULL值通常非常節省空間。

在OLTP方面,您有另一個問題。當你想插入一個實體時,你通常也想插入一堆屬性。一個插入現在變成了許多插入,並且您將要開始在交易中包裝這些插入,從而影響性能。

考慮到所有這些缺點,你可能會認爲從來沒有使用EAV模型。有一個地方給他們。當屬性隨時間變化時,它們特別有用。比如說,如果你有一個應用程序,用戶可以通過標籤輸入他們自己的信息。在這種情況下,混合方法是最好的解決方案。使用具有許多列的常規關係表作爲公共信息。使用EAV表爲每個實體的可選信息。

4

來源:維基

  1. 面向列的組織都聚集需要計算在許多行,但僅用於數據的所有列的一個顯着較小的子集時,更有效,因爲讀取數據的較小的子集可以比讀取所有數據更快。
  2. 當爲所有行同時提供新的列值時,面向列的組織效率更高,因爲可以高效地寫入列數據並替換舊列數據而不觸及行的任何其他列。
  3. 當同一時間需要單行的許多列時,以及當行大小相對較小時,面向行的組織效率更高,因爲可以使用單個磁盤查找來檢索整行。
  4. 如果在同一時間提供所有列數據的情況下寫入新行時,面向行的組織更高效,因爲可以使用單個磁盤查找來寫入整行。

實際上,面向行的存儲佈局非常適用於負載較重的OLTP類型的工作負載,並且交互式事務處理負載較重。面向列的存儲佈局非常適合類似OLAP的工作負載(例如數據倉庫),這些工作負載通常涉及所有數據(可能是千兆字節)上的較少數量的高度複雜查詢。

+1

當然你的正確,但問題沒有要求柱狀存儲:-) – dnoeth

3

除了Gordon Linoff提到的問題,EAV數據模型也非常難以查詢 - 找到所有的汽車製造商是寶馬,12到24個月之間的月份和成本< 10000變成了一大堆討厭的SQL ,尤其是如果你在數字上進行字符串比較...

0

通常,面向行和麪向列是低級別(磁盤)上的存儲機制。每個存儲的好處取決於您的要求。在某些情況下,面向列的存儲將會更好,在某些場景中,面向行的將是。

在Hbas數據庫中,他們使用列組的概念,即列組。

面向行的區別在於,由行構成的邏輯表按行塊存儲一行,而面向列的存儲每列塊一列。

當我們正在解析查詢時,面向行的結果是分析性的(如工資總額,工資平均值),但在我們需要訪問行的各個細節或插入新記錄時工作正常。儘管面向列的工作在分析查詢上很好,但導致插入單個記錄或訪問行的所有細節時表現不佳。

你可以訪問這個鏈接,這些鏈接描述了不同情況下他們的優點和缺點,以及他們的例子和他們的總結差異。

請點擊這裏:http://geekrandomstuff.blogspot.tw/2014/04/row-oriented-database-vs-column.html

0

從我的經驗EAV是偉大的,用於存儲應用程序設置IE瀏覽器。相對靜態的數據,而不需要進一步加入和轉換數據,除此之外就更不用說了。