【发布时间】:2011-09-08 20:46:39
【问题描述】:
设置:
当我在 stackexchange 上发现这篇很棒的文章时,我试图了解识别关系和非识别关系之间的区别。 What's the difference between identifying and non-identifying relationships?
在阅读了几篇 cmets 之后,我想到了另一个关于我一直遇到的问题的问题。
问题:
我应该在每个子表上使用多列主键吗?这样做的优点/缺点是什么?
为了更好地说明我的问题,我在下面创建了一个示例。我还包括了导致我提出这个问题的 cmets。
示例:
在我的情况下,我知道building_id,我需要得到bed.data。
#1 - 我当前的数据库结构:
TABLE { FIELDS }
-----------------------------------------------------------------------
building { id, data }
floor { id, building_id, data }
room {id, floor_id, data }
bed {id, room_id, data }
这种类型的表结构需要我使用一些连接来获取我需要的数据。没什么大不了的,但有点痛苦,因为我经常遇到这种情况。
#2 - 我对 Bill Karwin 建议的数据库结构的解释(参见下面的文章 cmets):
TABLE { FIELDS }
-----------------------------------------------------------------------
building { id, data }
floor { id, building_id, data }
room {id, building_id, floor_id, data }
bed {id, building_id, floor_id, room_id, data }
在我的情况下,这种表结构似乎消除了对连接的需要。那么这种表结构有什么缺点呢?我真的很喜欢不做这么多连接语句的想法。
来自文章的评论:
What's the difference between identifying and non-identifying relationships?
@hobodave:这是“约定优于配置”的论点。一些思想流派是,每个表都应该为一个名为 id 的单列伪键定义其主键,该伪键会自动生成其值。 Rails 等应用程序框架已将其作为默认设置进行普及。他们将自然键和多列键视为与其约定不同,在使用“遗留”数据库时需要。许多其他框架都效仿了这一做法。 – 比尔·卡尔文 2010 年 3 月 10 日 23:06
似乎“正确”构建识别关系会导致令人讨厌的巨大主键。例如楼有楼有房有床。床的 PK 将是 (bed_id, floor_id, room_id, building_id)。奇怪的是,我从未在实践中看到过这种情况,也没有听说过将其作为一种做任何事情的方法。那是PK中的大量冗余数据。 – hobodave 2010 年 3 月 10 日 23:34
@hobodave:我见过更大的多列主键。但我同意你的观点。考虑多列主键传达更多信息;您可以查询 Beds 表以获取特定建筑物中的所有床位,而无需进行任何连接。 – 比尔·卡尔文 2010 年 3 月 11 日 1:00
【问题讨论】:
-
有一点需要考虑。建筑物 ID 字段是否可以更改? (在这种情况下,您的更新代码需要使用 building_id 字段更新所有表)。如果 Building ID 是增量字段或标识字段,则不应更改,因此唯一的缺点是保留额外字段会使表变大。
-
我尝试保持两个 FK 列的名称相同,因此表构建将是:
building_id, data,而地板表将是:floor_id, building_id, data。当您使用由许多人长期开发的大型系统时,在您加入相同名称的情况下读取和编写查询会更容易。更不用说您的结果集不会包含您每次都必须别名的多个id列。 -
也许我们可以让@Bill Karwin 加入我们并指出我们是否误解了什么。
-
那太好了。有没有办法做到这一点?
标签: mysql database database-design database-schema mysql-management