2011-08-13 12 views
0

我有一個數據庫設計,其中我存儲圖像文件名在一個名爲resource_file的表中。數據庫設計中多個「項集」的方法

CREATE TABLE `resource_file` (
    `resource_file_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `resource_id` int(11) NOT NULL, 
    `filename` varchar(200) NOT NULL, 
    `extension` varchar(5) NOT NULL DEFAULT '', 
    `display_order` tinyint(4) NOT NULL, 
    `title` varchar(255) NOT NULL, 
    `description` text NOT NULL, 
    `canonical_name` varchar(200) NOT NULL, 
    PRIMARY KEY (`resource_file_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=592 DEFAULT CHARSET=utf8; 

這些「文件」是由另一臺聚集稱爲資源(這有點像一個專輯):

CREATE TABLE `resource` (
    `resource_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    `description` text NOT NULL, 
    PRIMARY KEY (`resource_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=285 DEFAULT CHARSET=utf8; 

這種設計背後的邏輯來得心應手,如果我要分配一定的例如,「資源」(專輯)到特定類型的「項目」(產品,用戶,項目&等)的類型:

CREATE TABLE `resource_relation` (
    `resource_relation_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `module_code` varchar(32) NOT NULL DEFAULT '', 
    `resource_id` int(11) NOT NULL, 
    `data_id` int(11) NOT NULL, 
    PRIMARY KEY (`resource_relation_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=328 DEFAULT CHARSET=utf8; 

這個表擁有資源到一定類型的項目的關係,如:

  • 產品
  • 用戶
  • 畫廊
  • &等

我做正是通過給「module_code」一個像「product」或「user」這樣的值並指定data_id添加到相應的unique_id,在這種情況下爲product_id或user_id。
因此,在這一天結束的時候,如果我想查詢分配到與123的ID我查詢resource_relation表產品的資源:(非常簡化的僞查詢)

SELECT * FROM resource_relation WHERE data_id = 123 AND module_code = 'product' 

這給了我資源的我可以找到相應的圖像。

  • 我發現這種方法非常實用,但我不知道這是否是一個正確的做法這個特殊的問題。
  • 這種方法的名稱是什麼?
  • 這是一個有效的設計?

謝謝

+0

如果您這樣做,請確保您在'module_code'上創建索引並通過它進行集羣。 – cdhowie

+0

我會牢記這一點!這是一種「壞方法」嗎?你怎麼看?請提供一些信息,如果你可以,我真的很感激!謝謝 – Herr

回答

1

先回答你的第二個問題:表resource_relationan Entity-attribute-value model的實現。

所以下一個問題的答案是,這取決於。根據關係數據庫理論,這是不好的設計,因爲我們不能強制執行data_idproduct_id,user_id等之間的外鍵關係。它也混淆了數據模型,並且可能難以進行影響分析。

另一方面,與您一樣,很多人會發現EAV是針對特定問題的實際解決方案,只有一張表而不是幾張。儘管如此,如果我們談論實用性,EAV不能很好地擴展(至少在關係產品中,有NoSQL產品會以不同的方式做事)。

從中可以看出,對於第一個問題的答案是否是正確的方法?是「嚴格的,不是」。但它有關係嗎?也許不是。


「我不能看到一個問題,爲什麼這個‘不會’的規模。你介意 解釋它遠一點?」

沒有與EAV兩個一般性問題。

第一個是小的結果集(如DATE_ID=USER_ID)和大的結果集(如DATE_ID=PRODUCT_ID)使用相同的查詢,這可能導致次優執行計劃。

第二個是向實體添加更多屬性意味着查詢需要返回更多行,而關係解決方案將返回相同數量的行幷包含更多列。這是主要的縮放成本。這也意味着我們最終編寫了可怕的查詢like this one

現在,在您的具體情況下,這些擔心可能都沒有關聯。我只是解釋EAV可能導致問題的原因。

「我將如何分配」資源「,例如,我的 產品表,」正常的方式「?

更常見的方法是爲每個關係e.g.USER_RESOURCES不同的交叉點表(AKA結合表),PRODUCT_RESOURCES等。每個表將包括複合主鍵,例如(USER_ID, RESOURCE_ID),可能沒有其他的東西了。

另一種方法是使用具有特定子類型表的通用超類型表。這是Damir has modelled的執行情況。超類型的正常使用caee是當我們有一堆相關的實體時,它們具有一些共同的屬性,行爲和用法,以及它們自己獨特的特徵。例如,PERSON和USER,客戶,供應商。

關於您的情況,我不認爲USER,PRODUCT和GALLERY符合這種方法。當然,他們都是RESOURCE的消費者,但這幾乎是他們所有的共同點。所以試圖將它們映射到ITEM超類型是一個procrustean解決方案;獲得一個通用的ITEM_RESOURCE表可能是您必須跳過其他地方的額外環節的小回報。

+0

我應該如何將「資源」分配給例如我的產品表「常規方式」? 我看不出一個問題,爲什麼這將「不」規模。你介意進一步解釋一下嗎? – Herr

2

enter image description here

這一個使用超類型/子類型。請注意主鍵如何從超類型表傳播到子類型表中。

+0

這似乎是一個很好的概念,你會介意填充一些示例數據嗎? 這將是完美的! +1 – Herr

0

我有一個數據庫設計,我將圖像存儲在名爲 resource_file的表中。

您不存儲圖像;你正在存儲文件名。文件名可能會或可能不會識別圖像。你需要保持數據庫和文件系統的權限同步。

您的resource_file表結構表示:「圖像文件名可在數據庫中識別,但在文件系統中無法識別。」它說因爲resource_file_id是主鍵,但除了該id之外沒有唯一的約束。我懷疑你的圖像文件實際上在文件系統中可識別的,你最好用適合現實的數據庫約束。也許對(文件名,擴展名)有一個唯一的限制。

資源表的原理相同。

對於resource_relation,您可能需要(resource_id,data_id)或(resource_id,data_id,module_code)上的唯一約束。但是。 。 。

我會盡力在稍後再提出這個問題。這很難弄清楚你想要做什麼resource_relation,這通常是一個紅旗。

+0

謝謝,您可以將「資源」視爲可分配給多個模塊(如產品,用戶或項目)的「相冊」。 帶來這種生活的關係是resource_relation,我分開data_id(應該與product_id,user_id或project_id匹配)和MODULE CODE,它指定「關係」屬於哪個模塊。這樣我就可以將「專輯」分配給我喜歡的任何模塊。例如product_id 78可以獲得專輯5,8和14.這是我嘗試去做的。我認爲它很好用。它只使用1個表格 – Herr