考虑这种情况:一个汽车从销售员买了。 营业员工作在陈列室 (和只在一个展厅)。 陈列室隶属于一家制造商 ,并且只销售该制造商制造的汽车。 与此同时,一个汽车是一个特定的模型 ,以及模型由一个制造商制造的。
限制R:汽车的型号的制造商必须是同一生产厂家作为汽车的营业员展示的附属制造商。
该图显示了明显的外键关系。
----> Manufacturer <----
| |
| |
Showroom |
^ |
| Model
| ^
Salesperson |
^ |
| |
--------- Car ----------
你如何强制限制R' 你可以添加一个外键关系Car --> Manufacturer
。 然而,汽车的制造商可以通过连接表拉上围绕“钻石”成立,所以当然要做到这一点就不会被标准化? 可是我不知道,否则如何强制约束。
如果我理解正确的问题,这应该是接近。
这里有几个关键细节
--
-- 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)
;
的方法,以确保该钻石的“底部”不能引用的钻石,最终导致钻石的不同的“顶”的“面”,就是用确定的关系和由此产生的“肥肉”自然键,所以他们可以在底部进行合并 :
(只显示了PK场,为了简便起见,你几乎肯定会希望有一个车辆识别号码作为备用钥匙Car
等...)
该ManufacturerId
已迁移下来两个菱形面,最终合并在底部成一个单一的领域。 张女士是申请单 ,确保不能有两个制造商导致同一辆车。
顺便说一句,这仍然不能阻止你使用代理键(除了这些土黄),假设DBMS支持FKS到备用钥匙:
代用项是在这个模型中单独服用多余的,但你可能有一些其他的实体存在,你还没有告诉我们,这可以从使用更薄FKS受益。
以上是您的图表,其中一辆车只存在一个卖汽车的最直接的转换。 不过,我怀疑你会希望能够存储尚未售出的汽车,当他们出售记住购车者等..
因此,一个更完整的模型将是这个样子:
我们只是冲洗和重复的识别关系伎俩,所以车不能显示在不同制造商的展厅,并且不能由销售人员从不同的展厅销售。
汽车是卖不出去的时候,只有一排Car
。 当有一行中的汽车销售Car
,并在相应的行Sale
。 无论Car
和Sale
共享相同的PK,这是一个“1〜0..1”的关系,这也可以通过合并模型Car
和Sale
,并制作销售的字段为空的,用适当的检查,以确保他们无法“部分NULL”。
顺便说一句,只要你是卖东西,你需要确保销售的“冻结时间”。 例如,购买者实际支付的价格应该不会改变,只是因为汽车的价格出售后改变。 看看这里获取更多信息。
文章来源: How to keep foreign key relations consistent in a “diamond-shaped” system of relationships