假设我有一个产品表(product
)和一个类别表(category
),并且它们之间通过补充表格存在多对多关系({{1 }})。
有没有办法制作一个,只有一个类别“主要”?
到目前为止,我有两个想法:
在product_category_xref
表product
中创建一个单独的列,并使其包含主要类别的键。
我不喜欢的是,数据中的冗余(primary_category
和primary_category
中定义的相同类别)或类别匹配(验证与product_category_xref
和primary_category
)。
创建product_category_xref.category
,is_primary
中的布尔列。
我不喜欢这个,可能有一种方法可以使几个类别成为主要类别。
此外,使用外键强制执行多对多关系的完整性,但我不知道如何仅强制执行一个主要类别(或者,当某个类别成为主要类别时,可能会生成所有其他类别的主要类别相同的产品非主要)。
最好的方法是什么?
更新:DBMS是通过PHP中的mysqli进行MySQL接口的。
UPDATE2:这就是我最终做的事情。
我在product_category_xref
表product_category_xref
中添加了一个不可为空的整数列。然后,主要类别是priority
最大的位置。作为一个有用的副作用,我也可以对类别进行排序。
我还添加了相同的东西,允许对一个类别中的产品进行排序。
当然,这使得更新数据变得更加困难,但这种情况不会经常发生。
答案 0 :(得分:3)
我不同意ypercube,他建议这种设计有效(无论DBMS如何)
请注意,在此设计中,有一个额外的表引用了您的多对多表,因此它同时包含产品和类别,但它的主键是只是产品。此设计强制执行以下两个要求:
此设计无法帮助您解决每个产品必须具有主要产品类别的限制,实际上只能通过在Product
表上添加强制外键列来实现。
然而,我不确定我是否会为您的问题推荐此解决方案。虽然这种设计成功地强加了您正在寻找的约束,但实际上在您的代码中使用它并不容易。您将不得不编写代码来处理产品类别的更改可能会影响您的主要产品类别的事实。该设计在数据的持久状态上运行良好,但它不利于数据更改。
由于您将需要一些程序逻辑来更改数据工作,您可能还会考虑更简单的数据库设计(例如,添加FK列Product.primary_category_id
)并编写程序逻辑以强加其他约束。这不是一种万无一失的方法,只是一种不同的,可能更容易理解(因此维持)的妥协。
要走哪条路,取决于您将尽可能多的约束推送到架构中的强烈程度。
答案 1 :(得分:1)
有一个解决方案可以考虑使用第二种方法:
它基于无效的唯一约束。
primary_product_id
。is_primary
将是无法使用的数字列
product_category_xref
表格,其长度为1
,CHECK
{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)
约束。答案 2 :(得分:0)
product_primary_cat_xref
形式的额外表格与产品的1&gt; 1关系以及与类别的m-&gt; 1关系将为您节省重复项,并且参考完整性不会不必要地冗余。< / p>