1

一个表可以有两个与列相同的外键吗?

即我有两张桌子,一张是Country,另一张是City。在国家表中:

国家
--------------
id
name
capitalcity <--- 这将有外键'city_id'。
populouscity <-- 这也将有一个外键“city_id”。created_at updated_at

CITY -------- id name
populous (bool) capital (bool) created_at updated_at





请记住,首都可能是也可能不是人口最多的城市。我想知道我是否应该将城市的两个布尔列分开,将城市作为只有名称的城市,并有一个引用城市的人口众多的表,以及引用城市的资本。并且在两个新表的国家表中有两个单独的外键?

4

2 回答 2

0

我会这样设计

COUNTRY
--------------
id
name    

CITY
-------
id
country_id   ( useful to know what country a city is in  )
name
created_at
updated_at

CAPITALS
----------
id
city_id         Unique

POPULUS
-------
id
city_id         Unique
于 2013-06-12T23:09:02.393 回答
0

好的,可以。人们有时会避免这种“明确”的 FK,因为它们不“灵活”,但如果你知道你总是需要与这两个城市完全相关,那么这是合适的设计。在任何情况下,您都不需要这些 FKbool 标志。

我看不到的是你如何将非首都和非人口最多的城市与这个国家联系起来。如果您不小心设计钥匙的方式,您最终可能会遇到这样的情况:一个城市可能成为它不属于的国家的首都。

使用标识关系可以避免这个问题:

在此处输入图像描述

因此,每个城市都由其所在国家/地区的数字 (CITY_NO) 标识。当 PK 从 CITY 迁移回 COUNTRY 时,COUNTRY_ID 会“合并”回其来源,因此不会出现国家/地区不匹配(请注意 COUNTRY.COUNTRY_ID 上的 FK1 和 FK2)。

CAPITAL_NO 和 POPULOUS_NO 可以保留为 NULL,因此它们可以暂时保持为 NULL 以解决由循环 FK 引起的先有鸡还是先有蛋的问题。这是有效的,因为 InnoDB 使用MATCH SIMPLE方法强制执行 FK,因此仅复合 FK 的一个组件为 NULL 就足以避免 FK 违规。

顺便说一句,考虑您是否真的需要 POPULOUS_ID - 如果您保留所有城市的人口,那么您只需找到 MAX 即可得出哪个城市人口最多。

如果您需要子 FK 或安抚您的 ORM,您可以随时添加代理键,例如 CITY_ID...

于 2013-06-12T23:48:27.057 回答