2013-05-17 27 views
2

我有一張名爲汽車的表,但每輛汽車都有數百個屬性,並且它們隨着時間的推移而不斷增加(馬力,扭矩,a/c,電動車窗等等)。我的表格有每個屬性作爲一列。當我擁有數千行和數百列時,這是正確的方法嗎?另外,我將每個屬性設置爲一個列,以便於高級搜索/過濾。如何在需要太多列時設計數據庫?

使用的MySQL數據庫

感謝

+1

什麼關於使用NoSQL的DB,就像MongoDB一樣。它將允許您的模式輕鬆更改(添加新屬性)。 – danieln

回答

4

這是一個有趣的問題恕我直言,答案可能取決於您的具體數據模型和實施。在這種情況下最重要的因素是數據密度

平均每行有多少實際填滿?

  • 如果你的大多數領域都始終存在,那麼數據範圍分區可能是要走的路。
  • 如果你的大多數領域都是空的,那麼狀結構(如@JayC建議)可能更有吸引力。

讓我們用你所提到的情況,並做一些模擬。

對於第一種情況,作用域分區,其思想是根據作用域或用途實現分區。作爲按使用情況進行分區的示例,假設大多數檢索的字段是「模型」,「年」,「製造商」和「顏色」。這些字段可以組成您的主[CAR]表,該ID字段的所有者將專門識別車輛。 現在我們假設發動機,馬力,扭矩和氣缸也會不時用於搜索,但不是那麼頻繁。這些可能存在於輔助表[CAR_INFO_1]上,該輔助表通過存在CAR_ID字段(外鍵)綁定到第一個表。繼續創建你需要的分區。

優點:更簡單的查詢。如果您執行聯合查詢(例如在VIEW中),則可以合併有關車輛的所有信息。

下行:維護。每一個新的領域,必須在模型本身來實現,需要更新的數據模型來找到您所需要的領域實際上存儲(或摘要視圖中。)

格式是更優雅,但需要更多的數據庫引擎。查看@ JayC's和@Nitzan Shaked的答案以獲取詳細信息。

優點:100%的數據密度。你永遠不會有空的數據值。另外維護 - 通過將其作爲一行添加到元數據標識符表中來創建新屬性。數據結構也不太複雜。

缺點:複雜的查詢,以及更復雜的執行計劃。假設您需要所有2010年製造的藍色福特汽車。這將是對第一種情況很簡單:

SELECT * FROM CAR WHERE Model='Ford' AND Year='2010' AND Color='Blue' 

現在的元數據結構化模型相同的查詢:

假設這兩個表的存在,

CAR_METADATA_TYPE 
ID DESC 
1 'Model' 
2 'Year' 
3 'Color' 

CAR_METADATA [CAR_ID], [METADATA_TYPE_ID], [VALUE] 

查詢本身會喜歡這樣的:

SELECT * FROM CAR, CAR_METADATA [MP1], CAR_METADATA [MP2], CAR_METADATA [MP3] 
WHERE MP1.CAR_ID = CAR.ID AND MP1.METADATA_TYPE_ID = 1 AND MP1.Value='Ford' 
AND MP2.CAR_ID = CAR.ID AND MP2.METADATA_TYPE_ID = 2 AND MP2.Value='2010' 
AND MP3.CAR_ID = CAR.ID AND MP3.METADATA_TYPE_ID = 3 AND MP3.Value='Blue' 

所以,這一切都取決於你的需求。但鑑於你的情況,我的建議是元數據格式。

(但做樣板清理第一 - 沒有重複的場,1:N的數據對自己的表,而不是像COLOR1,COLOR2,COLOR3,這種東西直列領域;))

4

我想最明顯的問題是,那麼,爲什麼不能有一個表car_attrs(汽車,ATTR,價值)?每個屬性是一行。大多數查詢都可以重寫爲使用此表單。

+0

我第二。我在多個dbs中使用這種方案,甚至不能提供產品的類型,就像你的例子。是一個很好且最快速的解決方案,並且可以擴展。 – kms

-2

如果您有更改屬性,請考慮將它們存儲在一個XML列或文本結構中的一列中。這個結構不是關係的。最重要的屬性將被複制到其他列中,因此您可以創建查詢來搜索它們,因爲Blob不能從SQL查詢中搜索。這將減少該表中的列數量並允許在不更改數據庫模式的情況下進行擴展。

正如其他人所建議的,如果你想在一個表中的所有屬性,然後使用屬性表來定義它們。那麼將取決於您的要求和應用程序的需求。

2

如果它是所有關於功能,創建一個features表,列出你所有的功能爲行,給他們某種自動ID,並創建一個car_features與外鍵到這兩個cars表和你features表將汽車與特徵聯繫起來,也許還有與這種關係相關的任何價值(一個乘客電動座椅等)。