2012-03-09 40 views
1

你好,stackoverflow社區!同一個數據庫表中的許多高度相似的對象

我正在研究一個相當大的數據庫驅動的Web應用程序。隨着更多組件的添加,底層數據庫的複雜性不斷增加,但迄今爲止,我已經完全沒有任何問題正常化數據。

但是,這個最終組件意味着一個可以容納產品的表格。 每個產品都有一個類別,根據類別的不同,它們有不同的字段。 爲每個產品類別製作表格似乎並不正確,因爲目前有五種類型,並且它們仍然有相當多的相同領域。 (但以奇怪的方式 - 描述和價格等幾個通用字段對於所有5個類別是共同的,但是一些屬性在1和2之間,其他3,4,5等等)共享。

我試圖擺脫EAV模型出於明顯的性能原因。

問題是,根據用戶想要輸入數據庫的產品類型,有一個(但不是完全)不同的字段結構 - 它們都有一個名稱和一般描述,但其他屬性如「覆蓋面積「只能應用於某些種類,如種子和農藥,但不適用於燃料,這種柴油/汽油布爾值和一些其他燃料相關屬性。

我應該只是提取一個表中的核心功能,併爲每個類別類型另外五個?未來這將很難擴展。

我目前的想法是讓產品表包含來自所有可能類別的所有字段,然後再用另一個表來描述產品表中的哪個類別具有哪些字段。

product:  id | type | name | description | price | composition | area covered | etc. 

fields:   id | name (contains a list of the fields in the above table) 

product-fields: id | product_type | field_id (links a bunch of fields to the product table based on the product type) 

我想這不會是太慢,易查(無需實際加入其他表,只是進行基於輸入的一些主要產品表搜索),它有助於之類的東西表單生成和數據驗證只需一個輕量級的附加查詢/連接。 (讀取從數據庫的產品,加入一個字符串實際使用的字段的連續清單 - 拆分和顯示基於它所包含的內容適當的表單字段,即實際與該產品相關的領域

感謝。你的麻煩! AndreiBârsan

回答

2

EAV實際上可以很好地存儲數據並在知道密鑰時再次獲取數據綁定。它還擅長添加字段而不更改模式。但是,當你需要WHERE field1 = x and field2 = y的equivilent時,它很差。

所以雖然我同意數據行爲很重要(有多少產品共享相同的字段等),使用該數據也是也是重要。

  • 哪些字段需要搜索,哪些字段是永遠只是數據存儲等

在大多數情況下,我建議保留這需要搜索所有領域,相互結合,在同一表。

在實踐中,這通常導致單個表格解決方案。

  • 新領域需要更改模式,新的索引,等等
  • 潛力人口稀少的數據,使用比「必要」
  • 允許簡單的查詢,簡單的索引和經常最快的查詢更多的空間
  • 通常,雖然不總是,但空間開銷很小

在稀疏數據開銷達到臨界點的情況下,然後我會朝着根據它們包含的字段分組的其他表ñ。更具體地說,我會不是按產品創建表。這是基於雙重假設,即大部分/全部字段將在至少產品中共享,並且這些字段將需要搜索。

這給出了一個模式更像......

Main_table (PK, Product_Type, Field1, Field2, Field3) 
Geo_table (PK, county, longitute, latitude) 
Value  (PK, cost, sale_price, tax) 
etc 

你也可以有一個元數據表說明哪些產品類型有哪些字段等

什麼這個模式可以讓一個更一組密集的表格,可以很容易地索引和快速搜索,同時通過對相關字段進行分組來最小化表格混亂和連接。


最後,沒有一個真正的答案,這一切都一個平衡的行爲。我的一般經驗法則是留在一張桌子上,直到我真的有一個真實而緊迫的理由,而不僅僅是理論上的理由。

+0

由於用戶將被允許基於幾乎任何列進行搜索,我猜主表+元數據表是最好的方法。我不認爲會有太多稀疏的條目(總共大約20列,最壞的情況是隻有11/20列,最好的情況是17/20)。 – 2012-03-09 16:31:45

+0

我用單桌+元表的方法去了,到目前爲止它的工作非常好!從長遠來看,我會看到它是如何實現的,但是鑑於目前的情況,我沒有看到有什麼特別的地方可以在壓力下解決這個問題。謝謝! – 2012-03-18 16:13:48

1

以我的經驗,除非你正在編寫一個完整的框架,可以呈現完整描述的字段(我們正在討論描述每個字段的大量元數據),不值得從主對象中分離字段定義。現代框架(如Grails)允許爲域/模型類和表添加新的虛擬零痛苦。如果您的通用字段重疊大約是所有對象類型之間的80%,我會將它們全部放在1個表中,並使用Table per Hierarchy inheritance model,其中descriminator字段可幫助您將對象類型分開。另一方面,如果您有20%的公共字段重疊,則使用帶有基類和表的常見字段的Table per Class繼承模型。而其他聯合表掛起基地。

+0

我使用的是CodeIgniter,只要腳本知道渲染條目的字段,我就不會有太多的表單渲染問題。 – 2012-03-09 16:23:27

1

我應該只是提取一個表中的核心功能,併爲每個類別類型另外五個?未來這將很難擴展。

這就是所謂的 - 子類型關係。如果大部分查詢都是以下兩種類型之一,則它工作得非常好:

  1. 如果您主要查詢SupetType表,並且只經常鑽取SubType表。
  2. 如果您在過濾到特定的SubType之後將查詢數據庫。
+0

不幸的是,搜索有時會潛入每個可能的類別領域。此外,還需要爲每種可能的產品類型添加一張新表,但這聽起來不太好。 – 2012-03-09 16:25:19

相關問題