【问题标题】:Confusion about 1:1 relationship对 1:1 关系的困惑
【发布时间】:2023-04-06 11:42:01
【问题描述】:

我一直在学习数据库设计,但我对 1:1 的关系感到困惑。据我了解,您可以简单地将列添加到相应的表中。有人可以提供一个真实世界的例子,说明一对一关系是必要的还是提供了一些显着的好处?即,我将在哪里使用 1:1 关系?它会是什么样子?

【问题讨论】:

  • 我会说是夫妻,但并不总是给定的。
  • 一个简单的案例——一个经理管理一个部门。但是,经理也是员工(但并非每个员工都是经理)。抽象出管理器表以帮助满足所有这些可能的约束是有意义的。 publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/…

标签: sql database-design


【解决方案1】:

如果 X 与 Y 具有 1:1 的关系并且 Z 也与 Y 具有 1:1 的关系,这很有用。Y 可以抽象到共享表中,而不是在 X 和 Z 中复制。

编辑:一个真实的例子是客户、公司和地址。客户和公司之间可能存在 N:N 关系。但是客户和公司都与地址具有 1:1 的关系。一些地址行可能与客户和个人相关。

【讨论】:

  • 但这不是意味着 X 和 Z 的比例是 1:1,所以他们可以一起生活吗?
  • 这使得 X 和 Z 可以间接相关,但这不是必需的。查看我的编辑以获取更真实的示例
【解决方案2】:

真正的一对一关系很少 发生在现实世界中。这类 建立关系通常是为了得到 围绕数据库的一些限制 管理软件,而不是 模拟真实世界的情况。在 Microsoft Access,一对一 关系可能是必要的 当您必须拆分数据库时 表分成两个或多个表,因为 安全或性能问题或 由于 255 列的限制 每桌。例如,您可以保留 大多数患者信息在 tblPatient,但要特别注意 敏感信息(例如,患者 姓名、社会安全号码和 地址)在 tblConfidential(见 图 3)。访问信息 在 tblConfidential 中可能更多 比 tblPatient 受限。作为一个 第二个例子,也许你需要 只传输大数据的一部分 表到某个其他应用程序 定期。您可以拆分表 进入转移和 非转移件,并加入他们 一对一的关系。

这是here: Fundamentals of Relational Database Design的引述

这是一个similar question

我可以看到使用 1:1(我过去曾使用过)的另一个原因是,如果您有一个包含很多列的表,并且只有少数列涉及非常密集和频繁的查询这需要快速,我会将它分成两个 1:1 相关的表,我可以在其中查询轻量级表并获得良好的性能,但仍然可以通过简单的连接轻松获得与之相关的其他数据。

【讨论】:

  • 不就是可以通过视图来控制安全和保密吗?事实上,这不是首选方法吗?然而,列限制听起来像是一个真正的限制,只能使用 1:1 来避免。
  • 我同意你关于安全性和保密性的看法,也许那篇文章没有最好的例子,但我可以肯定地看到,有时你会想要一些完全相关的数据 分离无论出于何种原因,可能是合法的 - 例如防止内幕交易的股票信息(我有朋友实际上已经看到这种类型的分离出于这个原因),或医疗(见乔尔的回答)等。
  • 我给了你一个赞成票(我想我现在可以这样做)并希望我能得到两个答案,但我认为 Joel Coehoorn 是我正在寻找的一个更具体的例子。
  • 实际上,1:1 的关系并不少见,但大多数 Microsoft Access 开发人员似乎对超类型和子类型知之甚少。例如,请参阅此 SO 问题的公认答案:stackoverflow.com/questions/4969133/database-design-problem
  • @catcall:我认为关键在于它们在现实世界的关系中是一种不常见的关系,但它们在数据建模中的使用(甚至有时经常)是出于定义关系以外的原因。
【解决方案3】:

我会给你一个真实的例子。

在医疗计费领域,希望通过医疗保险获得报酬的医生通过为患者的每次就诊创建听写报告来处理计费。这实际上可能是秘书转录的录音,但更多情况下,它只是对他们与患者所做和谈论的事情的书面描述,以及历史、印象等。然后,获得许可的医疗编码员将阅读此命令并决定允许医生开具的账单。

除了听写之外,还有有关患者的人口统计信息:姓名、年龄、账单地址等。这些信息必须与听写信息严格分开,以防止编码人员允许偏见影响他们的计费判断或侵犯患者的隐私。

这些数据通常在原始点的数据系统中以 1:many 关系保持良好规范化,并且只有正确的部分在正确的时间显示给正确的人。然而,大量办事处将其计费功能外包给第三方。例如,这样一家小型诊所就不必在工作人员中配备有执照的医疗编码员;计费办公室的一名编码员可以处理许多诊所的需求。当数据从诊所发送到计费办公室时,患者人口统计信息和听写需要作为单独的部分,可能在不同的时间出现。此时,它们可能会以 1:1 的关系和共享 ID 字段存储在完全独立的表中,以便以后进行匹配。

在这种情况下,1:1 关系与数据模型关系不大。您可能会在导入时匹配记录,并且随着账单在系统中移动,最终在诊所的人口统计记录中收到的省级患者信息将与真实的人匹配,因此可以恢复 1:many 关系。否则,每次就诊时,您都会在单独的帐户上获得一份单独的对帐单。

相反,它几乎与系统设计有关。在我们想象的计费服务中,构建和使用计费部分与编码部分的人可能完全不同。这样,每一方都可以完全控制自己的领地,并且您可以确定没有人,甚至是开发人员,都不会违反任何隐私规则。

【讨论】:

  • 这也是一个简洁有效的例子。我喜欢它。
  • 天哪,这很复杂。那么,在这种情况下,是确保数据的某些部分绝对分离,而不是实体模型中的某些要求?
  • +1 - 很好的答案!在大学实习期间,我在保险系统上工作了很短的时间,虽然这个案例从未出现在我所做的工作中,但这很有意义。感谢@Joel 的回答!
【解决方案4】:

我相信表格应该设计有领域背景。因此,如果这些列形成两个不同的实体,则不应将它们混合在一个表中。根据我的经验,随着时间的推移,1:1 关系往往会演变成 1:n 关系。

例如,您可能想要存储一个人的 邮政地址。但一段时间后,您需要每人存储多个地址。将程序从 1:1 关系重构为 1:n 通常比将旧表中的某些列提取到新表中要容易得多。

许多数据库系统允许以非常简单的方式定义每个表的访问权限。但是为各个列定义权限通常很痛苦。

【讨论】:

    【解决方案5】:

    1:1 关系是您在数据中建模的抽象概念,但在数据库级别(假设为 RDBMS)并不真正存在。您总是在一个表上有一个指向另一个表的外键,因此从技术上讲,FK 指向的父表可能有多个子表。这是您希望在业务逻辑中强制执行的内容。

    在建模意义上的 1:1 关系的一个很好的例子是员工和个人之间的关系。您有一个拥有某些数据的人,然后您对同一个人拥有额外的属性,就像您赋予员工一样。用 OO 编程术语来考虑这一点的一个好方法是继承类。 Employee 类,继承自 Person。事实上,ORM 系统可能会在数据库中建模 1:1 关系,每个表都有一个共享的主键。

    【讨论】:

    • 小心将“1:1”与“1:0 or 1”混淆
    • 1:(1or0) 是 1:1 关系的情况。这是对该关系的约束,但该关系(如果存在)仍然是 1:1,并且由于 FK,在 db 中仍然是 1:N。
    • -1?真的。这是有效的。重要的是要知道建模与您在数据库中实际拥有的不同。
    • 没关系,我可能只是解释不清楚,或者跑题了。请随意投票给我,我可能正在获得同伴压力徽章的路上:)
    【解决方案6】:

    首先,因为他们在谈论 Access(Jet、Ace 等等)——感谢@Richard DesLonde 发现了这一点——然后他们可能在谈论 1:0..1 的关系。我不相信真正的 1:1 关系在 Access 中是可行的,因为它没有延迟约束的机制,也没有在 SQL PROCEDURE 中执行多个语句的机制。大多数 Access 从业者都满意地使用 1:0..1 关系来模拟真正的 1:1 关系,所以我猜作者很满意地使用术语“1:1”来非正式地指代两者。

    当然,1:1 和 1:1..0 的关系在现实世界中很常见。我宁愿认为他们试图传达一个(有效的)观点,即出于业务目的在数据模型中发明了一些 1:1 和 1:1..0 关系。

    考虑一个“自然人”(即人类)和一个“公司”。它们没有共同的属性(当然,两者都有一个“名称”,但它们的域不同,例如“自然人名”具有“姓氏”、“名字”和“头衔”等的亚原子域)。

    但是,在给定的数据模型中,不同的实体类型可能扮演相同的角色。例如,“自然人”和“公司”都可以是“公司”的官员。在数据模型中,我们可以有两种不同的实体类型“自然人官员”和“公司官员”,它们可能具有许多共同的属性并且来自相同的域,例如任命日期、终止日期等;此外,它们的业务规则将是相同的,例如任命日期必须早于终止日期。此外,两者都将参与等价关系,例如“自然人代表”等

    数据模型可以在较高级别“拆分”,从而产生非常相似的表对,例如“自然人官员”和“公司官员”、“自然人官员自然人代表”和“公司官员自然人代表”等。

    但是,另一种方法是使用虚构的实体类型对公共属性和关系进行建模。例如,“自然人”和“公司”都可以被认为是“法人”(顺便说一句:法律上有“法人”这样的概念,但这与现实中存在的意思相同吗?世界?!)

    因此,我们可以有一个“法人”的超类表和“自然人”和“公司”的子类型表。 “官员”表将引用“法人”表。所有后续的关系表都可以引用“officers”表,这将使从现在开始的表数减半。

    这种“子类化”方法存在实际问题。因为“自然人”和“公司”没有共同的属性,他们没有共同的密钥,因此“法人”表需要有一个人工密钥,这会带来所有问题,特别是如果它需要暴露在应用程序中。此外,由于“法人”、“自然人”和“公司”之间的关系确实是 1:1 的,因此某些 DBMS,如 Access,将缺乏有效实施它们的必要功能,许多人将不得不满足于使它们成为 1: 0..1.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 2018-03-05
      • 1970-01-01
      • 2013-06-12
      • 2017-07-08
      • 2020-12-20
      • 1970-01-01
      相关资源
      最近更新 更多