考虑一下这种情况:Car是从销售人员购买的。销售人员在展厅工作(只有一个展厅)。展厅隶属于制造商,只销售该制造商生产的汽车。同时,汽车是特定的模型,模型是由制造商制造的。
限制R:汽车模型的制造商必须是同一制造商的汽车的销售人员展厅的附属制造商。
该图显示了明显的外键关系。
----> Manufacturer <----
| |
| |
Showroom |
^ |
| Model
| ^
Salesperson |
^ |
| |
--------- Car ----------你如何执行限制R?您可以添加一个外键关系Car --> Manufacturer。然而,汽车制造商可以通过围绕“钻石”的各种方式连接表格来建立,因此,这样做肯定不会正常化吗?然而,我不知道如何强制执行这一约束。
发布于 2012-09-05 20:41:30
如果我正确地理解了这个问题,那就差不多了。

这里有几个关于钥匙的细节
--
-- Keys for SalesPerson
--
alter table SalesPerson
add constraint PK_salesperson primary key (PersonID)
, add constraint AK1_salesperson unique (ManufacturerID, ShowRoomNo, PersonID)
, add constraint FK1_salesperson foreign key (PersonID)
references Person (PersonID)
, add constraint FK2_salesperson foreign key (ManufacturerID, ShowRoomNo)
references ShowRoom (ManufacturerID, ShowRoomNo)
;
--
-- keys for Sale table
--
alter table Sale
add constraint PK_sale primary key (SaleID)
, add constraint FK1_sale foreign key (BuyerID)
references Person (PersonID)
, add constraint FK2_sale foreign key (ManufacturerID, ModelName, ShowRoomNo)
references CarDisplay (ManufacturerID, ModelName, ShowRoomNo)
, add constraint FK3_sale foreign key (ManufacturerID, ShowRoomNo, SalesPersonID)
references SalesPerson (ManufacturerID, ShowRoomNo, PersonID)
;发布于 2012-09-06 11:55:03
要确保钻石的“底部”不能引用最终导致钻石“顶部”不同的“边”,方法是使用标识关系和由此产生的“胖”自然键,这样就可以将它们合并到底部的:

(为简洁起见,只显示PK字段。您几乎可以肯定地希望在Car等.中使用车辆识别号作为备用密钥。
ManufacturerId已经被迁移到两个钻石边,并最终在底部合并成一个单一的字段。事实上,这是的单一文件,确保不能有两家制造商导致同一辆汽车。
顺便说一句,这仍然不能阻止您使用代理键(除了这些自然属性之外),假设DBMS支持FKs到备用键:

在这个单独使用的模型中,代理是多余的,但是您可能有一些其他实体没有展示给我们,这些实体可能从使用更瘦的FKs中受益。
以上是最直接的转换你的图表,其中一辆汽车只存在作为一辆出售的汽车。然而,我怀疑你会想要能够存储尚未售出的汽车,当它们被出售时,记住汽车购买者等等。
因此,一个更完整的模型应该是这样的:

我们只是冲洗和重复识别关系技巧,这样一辆汽车就不能展示在不同制造商的展厅里,也不能由来自不同展厅的销售人员出售。
当Car中只有一行时,一辆汽车就不卖了。当Car 中有一行,中有对应的行时,汽车就被出售了。Car和Sale共享相同的PK,这是一个"1到0.1“的关系,也可以通过合并Car和Sale来建模,并使sale的字段为空,并进行适当的检查,以确保它们不能”部分为空“。
顺便说一句,每当你在卖东西的时候,你都需要确保销售是“冻结在时间里的”。例如,买者实际支付的价格不应该仅仅因为汽车的价格在出售后发生变化而改变。查看here获取更多信息。
https://stackoverflow.com/questions/12288579
复制相似问题