假设我们有以下数据库:
或者伪sql格式(所有列都不为空):
create table road (
id int PK
)
create table item_on_road (
id int PK
road_id int FK road.id
position_order int
UNIQUE (road_id, position_order)
)
create table rock (
id int PK FK item_on_road.id
size float
)
// and so on
我们有一辆road
可以朝一个方向行驶的车。
沿着这条路,我们可以找到不同的东西,item_on_road
以便我们遇到它们,position_order
例如1,2,3
我们在路上发现的东西可能会有所不同,从sign
到gas_station
。
现在我想问一个问题:
这个数据库设计是否符合db 1-5th范式?我认为不会,因为我们可以
item_on_road
在没有相应的情况下创建条目rock
如果它不符合第五范式,该怎么办?
可选问题:
如果1个问题的答案是肯定的,如何确保
rock
ifitem_on_road
create的存在?如果 1 个问题的答案是肯定的,如何确保我们无法创建
rock
并sign
指向相同的 id?
第五范式是关于定义有效组合的集合,如果您需要在数据库设计中强制执行的话。
这并不是要求引用表中存在一行。我不知道有任何范式可以做到这一点。
例如,如果您需要使数据库设计强制规定岩石只能出现在道路 12 和 34 上,您将分解为另一个表来表示有效组合。
您当前的设计允许岩石出现在任何道路上。如果这是您的意图,那么它符合第五范式。
问题3&4:如何保证存在子行,并且一个item只能是一种类型的item?
您需要反转引用:
在 中添加 rock 的外键列
item_on_road
,它引用该rock
表:该外键列可以为空。如果该物品是岩石,则填写该值。如果该项目不是石头,则将其保留为空。
为其他类型的项目添加更多列。
然后添加 CHECK 约束以确保这些外键列之一恰好为非空。