数据库表上的 1 对 1 关系有味道吗?

Posted

技术标签:

【中文标题】数据库表上的 1 对 1 关系有味道吗?【英文标题】:Do 1 to 1 relations on db tables smell? 【发布时间】:2009-02-27 19:56:18 【问题描述】:

我有一个包含一堆字段的表。这些字段可以分成逻辑组——比如工作的项目经理信息。分组本身并不是真正的实体候选者,因为它们没有也不应该有自己的 PK。

目前,为了对它们进行分组,字段具有前缀(例如 PmFirstName),但我正在考虑将它们分成多个表,在主表上具有 1:1 关系。

我这样做时有什么需要注意的吗?这只是一个糟糕的选择吗?

我可以看到,也许我的查询会因为所有额外的连接而变得更加复杂,但可以通过视图来缓解,对吗?如果我们谈论的是记录少于 10 万条的表,这会对性能产生显着影响吗?

编辑:我将进一步证明非实体候选人的想法。此信息由我们的用户群输入。他们不了解/不关心彼此。因此,同一个用户可能会提交相同的“projectManager 名称”或在这一点上不会违反任何约束的任何内容。如果我们想关联来自不同用户的条目,我们可以稍后确定。如果我给这些东西自己的键,它们将以与主表相同的速度增长——因为它们本质上是同一个实体的一部分。没有 pt 是用户从可用的“项目经理”列表中挑选的。

因此,鉴于上述情况,我认为它们不是实体。但也许不是 - 如果您有进一步的想法,请发布。

【问题讨论】:

骗子:***.com/questions/517417/… 搜索“1:1 关系”并未产生该结果。很抱歉被骗了 【参考方案1】:

除非有特定的性能原因,否则我通常不使用 1 对 1 关系。例如将不常用的大文本或 BLOB 类型字段存储在单独的表中。

我怀疑这里还有其他事情发生。在您给出的示例中 - PmFirstName - 似乎应该有一个与“ProjectManagers”或“Employees”表相关的单个 pm_id。您确定这些分组都不是真正的实体候选者吗?

【讨论】:

对于 SQL Server? Blob 存储在普通页面之外,所以我认为它们不需要放在单独的表中。【参考方案2】:

对我来说,它们有异味,除非对于某些行或查询,您不会对额外的列感兴趣。例如如果对于大部分查询,您没有选择 PmFirstName 列,或者对于大部分行,这些列是 NULL。

我喜欢气味标签。

【讨论】:

【参考方案3】:

我对类继承结构使用一对一关系。

例如,所有债券都有一些基本信息,例如 CUSIP、Coupon、DatedDate 和 MaturityDate。这一切都在主表中。

现在每种类型的债券(Treasury、Corporate、Muni、Agency 等)也有自己独特的一组列。

在过去,我们只有一张非常宽的桌子,里面包含所有这些信息。现在我们将特定于类型的信息分解到单独的表中,这给了我们更好的性能。

目前,为了对它们进行分组,字段具有前缀(例如 PmFirstName),但我正在考虑将它们分成多个表,在主表上具有 1:1 关系。

创建一个人表,每个数据库都需要这个。然后在您的项目表中有一个名为 PMKey 的列,它指向人员表。

【讨论】:

【参考方案4】:

为什么感觉这组字段不是实体候选项?如果不是,那么为什么要尝试用前缀来标识它们?

要么删除前缀,要么将它们提取到自己的表中。

【讨论】:

【参考方案5】:

如果它们是可以在其他地方使用的独立逻辑实体,那么将它们分成单独的表是很有价值的。

因此,“项目经理”可能与当前的所有项目是 1:1 的,但稍后您可能希望让项目经理拥有多个项目是有道理的。 所以有额外的桌子很好。

如果您有 PrimaryFirstName、PrimaryLastName、PrimaryPhone、SecondaryFirstName、SecondaryLastName、SEcondaryPhone

您可以只拥有一个包含 FirstName、LastName、Phone 的“Person”表

那么你原来的Table只需要“PrimaryId”和“SecondaryId”列来替换你之前的6列。

此外,使用 SQL,您可以跨物理位置拆分文件组和表。 因此,您可以有一个 POST 表和一个 COMMENT 表,它们具有 1:1 的关系,但 COMMENT 表位于不同的文件组中,并且位于具有更多内存的不同物理驱动器上。

1:1 并不总是有气味。除非它没有目的。

【讨论】:

以上是关于数据库表上的 1 对 1 关系有味道吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在laravel中通过id选择不同表上的关系数据

多个表上的雄辩的自定义“属于”关系

数据类型(字段)表上的雄辩关系

关系表上的NodeJS PostgreSQL Express SequelizeEagerLoadingError

Laravel where() 和 orderBy() 在外部服务器上的关系表上

根据两个不同表上的两列对完全连接进行排序