如何在多对多关系中创建一个主链接?

时间:2013-11-23 12:14:41

标签: database-design

假设我有一个产品表(product)和一个类别表(category),并且它们之间通过补充表格存在多对多关系({{1 }})。

有没有办法制作一个,只有一个类别“主要”?

到目前为止,我有两个想法:

  1. product_category_xrefproduct中创建一个单独的列,并使其包含主要类别的键。 我不喜欢的是,数据中的冗余(primary_categoryprimary_category中定义的相同类别)或类别匹配(验证与product_category_xrefprimary_category)。

  2. 创建product_category_xref.categoryis_primary中的布尔列。 我不喜欢这个,可能有一种方法可以使几个类别成为主要类别。

  3. 此外,使用外键强制执行多对多关系的完整性,但我不知道如何仅强制执行一个主要类别(或者,当某个类别成为主要类别时,可能会生成所有其他类别的主要类别相同的产品非主要)。

    最好的方法是什么?

    更新:DBMS是通过PHP中的mysqli进行MySQL接口的。

    UPDATE2:这就是我最终做的事情。 我在product_category_xrefproduct_category_xref中添加了一个不可为空的整数列。然后,主要类别是priority最大的位置。作为一个有用的副作用,我也可以对类别进行排序。 我还添加了相同的东西,允许对一个类别中的产品进行排序。 当然,这使得更新数据变得更加困难,但这种情况不会经常发生。

3 个答案:

答案 0 :(得分:3)

我不同意ypercube,他建议这种设计有效(无论DBMS如何)

ERD

请注意,在此设计中,有一个额外的表引用了您的多对多表,因此它同时包含产品和类别,但它的主键是只是产品。此设计强制执行以下两个要求:

  • 主要产品类别是有效的产品类别组合。
  • 每种产品最多只有一个主要产品类别。

此设计无法帮助您解决每个产品必须具有主要产品类别的限制,实际上只能通过在Product表上添加强制外键列来实现。

然而,我不确定我是否会为您的问题推荐此解决方案。虽然这种设计成功地强加了您正在寻找的约束,但实际上在您的代码中使用它并不容易。您将不得不编写代码来处理产品类别的更改可能会影响您的主要产品类别的事实。该设计在数据的持久状态上运行良好,但它不利于数据更改

由于您将需要一些程序逻辑来更改数据工作,您可能还会考虑更简单的数据库设计(例如,添加FK列Product.primary_category_id)并编写程序逻辑以强加其他约束。这不是一种万无一失的方法,只是一种不同的,可能更容易理解(因此维持)的妥协。

要走哪条路,取决于您将尽可能多的约束推送到架构中的强烈程度。

答案 1 :(得分:1)

有一个解决方案可以考虑使用第二种方法:

它基于无效的唯一约束。

  • 从产品表中添加一个额外的null外键 product_category_xref表,名为primary_product_id
  • is_primary将是无法使用的数字列 product_category_xref表格,其长度为1CHECK {1}的可能值的约束,1值将显示 is_primary为true,null值显示none-primary。
  • CHECK约束,其值为:
    (primary_product_id is null or ((primary_product_id = product_id) and (is_Primary is not null)))
  • UNIQUE上的(primary_product_id + is_primary)约束。

SQLFIDLE sample (tested on oracle).

答案 2 :(得分:0)

product_primary_cat_xref形式的额外表格与产品的1&gt; 1关系以及与类别的m-&gt; 1关系将为您节省重复项,并且参考完整性不会不必要地冗余。< / p>