2011-04-21 81 views
2

我有許多產品可以分別處於多個類別中。用一個「主」值實現多對多

products: id, ... 
products_categories: product_id, category_id 
categories: id, ... 

現在我想有很多產品,每一個主類別,0個或更多個二級類別中。我可以想出兩種在SQL中對其進行建模的方法。

  1. 添加is_primaryproducts_categories OR

  2. 添加primary_category_idproducts

什麼是純粹的SQL和/或ActiveRecord的實現這一目標的最佳方式是什麼?我正在使用PostgreSQL,因爲它值得。

回答

1

我會第一個選項去,除非我有一個很好的理由選擇2(如額外的成本獲取主類別時加入)

原因:你可能需要添加主類別PRODUCT_CATEGORY無論如何(爲了使用它在一個統一的和簡單的方式在查詢,如獲取產品的所有類別) 選項1避免重複的主要類別,因此更簡單

1

我會去選項(1)。原因是因爲您的產品可以屬於多個類別,關係屬性(它是「主」類別)屬於定義關係的表中。

我甚至會走得更遠,並建議不要標記字段'is_primary',而應該將該字段標記爲'association_type'。而不是僅僅添加一個位域,將其設爲一個整數域,並且定義了所有的關聯類型。在你的情況下,只有兩種關聯類型 - 次要和主要。優點是這種設計更具可擴展性。如果明天要求您定義「主要」,「次要」和所有其他大類,則此設計將能夠處理它,而不必添加另一個字段來指定「次要」字段。

1

這實際上取決於你想要完成的具體細節。以下是決定最適合你的一些事情。其他答案已經解決了第一個案例,所以我將着重討論第二個案例。

如果你有primary_category_id

  • 看來吸塵器在product告訴這category是主要的一個,而不是在每一個product_category在一個行0在具有1一個字段一個字段隔行排列,儘管MR使用association_type的建議聽起來也很乾淨 - 但您有什麼機會擁有「高等」類別?
  • 這是稍微容易得到主要類別
  • 可以很容易地確保每一個產品總有一個主要類別(只是讓現場NOT NULL
  • 它會自動強制執行,一個產品只能有一個主類
  • 您是否還應將主要類別插入products_categories
    • 這兩個選項都沒有強制執行。
    • 如果不這樣做,這是尷尬查詢所有類別
    • 如果你這樣做,它仍然很容易地查詢,但沒有額外的工作,沒有什麼可以保證主要類別也插入到另一個表

如果您使用is_primary方法,您應該以某種方式確保每個產品總是隻有一個主要類別。

0

每種方式的優點和缺點是什麼?

選項1.我可以肯定,產品的主要類別確實是其中的一個類別。但是可能存在確保產品不超過一個主要類別的問題。

選項2.這讓我確保產品只有一個主要類別。但是,我似乎沒有辦法確保它是同一產品類別中的一種。

所以,我可能會去一個第三個選項,使用表​​:

Products_PrimaryCategories: product_id, category_id 

似乎一樣product_categories,但有一些附加屬性:

  • product_id有一個關聯的唯一索引,確保每個產品只能有一個主要類別;

  • (product_id, category_id)是一個外鍵引用products_categories (product_id, category_id)確保產品的主要類別是之一其類別(這意味着(product_id, category_id)應該是products_categories的主鍵)。