mysql / FoR数据库设计

时间:2013-06-12 22:44:50

标签: mysql database ruby-on-rails-3 database-design

表是否可以使用两个与列相同的外键?

即。我有两张桌子,一张是乡村,另一张是城市。在国家/地区表中:

COUNTRY
    --------------
ID
命名
capitalcity< ---这将有外键'city_id' populouscity< - 这也有一个外键'city_id'。 created_at 的updated_at

CITY
    -------
ID
命名
人口稠密(布尔)
资本(布尔)
created_at
的updated_at

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

我没有看到的是你如何将非首都和非人口最多的城市连接到这个国家。如果你不小心你如何设计你的钥匙,你最终可能会遇到一个城市可能成为它不属于的国家的首都的情况。

使用识别关系可避免此问题:

enter image description here

因此,每个城市都由其国家/地区内的数字(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就可以得出哪一个人口最多。

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