2012-10-17 177 views
1

考虑我们有2个表如下所示:关系数据库设计方案

products:  id, name 
        (PK = id) 
product_group1: product_id 
        (PK = a1_id) 
        (FK = a1_id REFRENCES a1) 
product_group2: product_id 
        (PK = a1_id) 
        (FK = a1_id REFRENCES a1) 
product_group3: product_id 
        (PK = a1_id) 
        (FK = a1_id REFRENCES a1) 

的问题是,我想设计一个表叫做approved_products只接受来自1与组2(不是第3组)的产品。

我该如何设计这样的表格? (我正在使用mysql BTW)

+0

如何让'approved_products'中的唯一列成为'product_group1'和'product_group2'的外键? – ecbrodie

+0

不,考虑我们想在另一个表中引用'approbed_products'表。 – assembler

+0

如果MySQL支持计算列或检查约束,这将是微不足道的。唉,事实并非如此。 –

回答

1

无法在触发器或应用程序级别插入某些逻辑,但无法用当前设计解决此问题。 FOREIGN KEY s不能引用多个表格(我了解您的设计使用每个产品组的一个表格,如果我错了,请让我知道)。此外,它们不能包含任何条件逻辑,因此即使您有一个product_groups表,也不能创建仅允许来自该表的G1和G2记录的FOREIGN KEY

为了使用标准关系完整性约束来实现这一点,您需要一个名为approvable_products的附加表,其中包含product_ids这些产品在组1或组2中。

1

你想要的是“否定的”外键约束,即拒绝产品ID出现在这个表中。

但是,这是不可能的。你必须保留这样的表格 - 只包含组1和2中的ID - 你自己;你可以使用触发器。之后,您将使用该表作为外键参考表。

+0

你的意思是,没有使用触发器的关系数据库没有办法做到这一点? – assembler

+0

@assembler我没有说你必须使用触发器,但它可能是最安全的,因为它也会在你的代码之外运行。 –

+0

我真的想使用数据库参照完整性的能力,我认为可以有一种方法来做到这一点,而无需使用触发器或任何其他手动验证控制 – assembler

1

你应该设计你的表像如果“规则” didnt存在(因为,让我们面对它,它可以最终改变)

然后,您可以使用其他机制来实现这一contraint。如果您想在数据库级别执行此操作,则可以在表上使用before insert触发器,或者对调用验证数据的函数的列进行检查。但为什么不在你的申请上做呢?这对我来说似乎是一种商业规则。