与同一实体的多个关系

时间:2016-12-10 21:06:19

标签: database database-design relational-database

我有两个实体:

人(的 ID 下,名称)

城市(的 ID 下,latCoord,longCoord,名称)

每个人都应该有一个出生城市,一个工作城市和一个家乡城市。

建模这些关系的正确方法是什么:

1-在人与城市之间添加三个外键

2-创建关系表,按如下方式映射关系

person_city_rel_type(ID,类型)

(1, “出生”)

(2, “工作”)

(3, “家庭”)

person_city(person.id,city.id,person_city_rel_type.id)

1 个答案:

答案 0 :(得分:1)

同一个表的多个FK(外键)没有任何问题。只要声明一些FK,只要某些列的子行总是显示为其他列的子行(如果这不是其他声明的FK的结果)。

所以直截了当的设计更好:

person1(id,name, birthCity, workCity, homeCity)
city(id, latCoord, longCoord, name)

另一种直截了当的设计是:

person(id, name)
city(id, latCoord, longCoord, name)
birth_city(id, cityId)
work_city(id, cityId)
home_city(id, cityId)

此处有一项限制,您需要为每个 X 添加该 select id from X _city = {{1 ,即FKs与人的两种方式。但是,如果每个城市的人的信息是可选的,那么只有FK约束引用人的这些表是自然的。

而在您的替代设计中,数据库状态仅在person,person_city甚至person_city_rel_type具有满足某个复杂约束的值时才有效。也就是说,每个人身上的id,只有个人的id,在person_city中出现,具有三个类型值id,person_city_rel_type恰好具有该值。即满足某个复杂约束,包括某些选择select id from person等于 X _citys,并且如上所述它们是from person_city_rel_type join person_city的投影。

当你开始看到需要保持的约束表达方式时,可以考虑更简单的表格。

PS你的第二个提案也可能适用于person1。确实,这允许使用无效的类型值,而在设计中获得无效的person_city(假设为person_city_rel_type_id FK),则必须搞砸person_city_rel_type。但架构并没有真正阻止你这样做。两种设计都需要将类型列约束为三个值。因此,使用id而不是字符串并不能解决这个问题。