1:1关系的混淆

7

我一直在学习数据库设计,对于1:1关系感到困惑。据我所知,您可以简单地向适当的表中添加列。能否有人提供一个现实世界的例子,说明何时需要或者获得了哪些重要优势?也就是说,我在什么情况下会使用1:1关系,它会是什么样子?


6
我会说“夫妻”,但并非总是如此。 - Owen
一个简单的案例 - 一个经理管理一个部门。然而,经理也是一名员工(但并非每个员工都是经理)。将经理表抽象出来有助于满足所有这些可能的约束条件。http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/admin/c0004733.htm - JasCav
6个回答

6
我将为您提供一个实际的应用例子。
在医疗账单领域,希望从医保得到支付报酬的医生通过为每次与患者接触的就诊创建一份口述报告来处理账单。这可能实际上是由秘书记录的音频口述文本转录而成,但更常见的是只是对他们与患者所做和讨论的事情的书面描述,以及有关患者历史、印象等等。然后,经过认证的医疗编码员将阅读此口述报告并决定医生可以申报的费用。
与口述报告分开的是与患者相关的人口统计信息:姓名、年龄、账单地址等等。必须严格将这些信息与口述信息分开,以防止编码员允许偏见影响其账单判断或侵犯患者隐私。
这些数据通常会在起源点的数据系统中通过1:多的关系进行规范化处理,并且只有正确的部分在正确的时间显示给正确的人。然而,很多办公室将其账单功能外包给第三方。例如,一个小诊所不必聘请持牌的医疗编码员;一个收费员可以处理许多诊所的需求。当数据从诊所发送到收费办公室时,患者的人口统计信息和口述报告需要作为独立的部分传输,可能在不同的时间传输。此时,它们很可能被存储在完全独立的表格中,具有1:1的关系,并具有一个共享的ID字段以便后期匹配。
在这种情况下,1:1的关系与数据模型几乎没有任何关系。您可能可以在导入时匹配记录,在账单通过系统时,最终从诊所人口统计记录中接收到的省级患者信息将被匹配到一个真实的人身上,以便恢复1:多的关系。否则,每次看医生都会得到一个单独的账单。
相反,这几乎完全关乎系统设计。我们想象中的收费服务很可能完全由不同的人构建和使用账单部分和编码部分。这样,双方都可以完全控制自己的领地,并确保没有人,甚至是开发人员,违反隐私规则。

这也是一个整洁且有效的例子。我喜欢它。 - richard
天哪,这太复杂了。所以,在这种情况下,它是为了确保数据的某些部分绝对分离,而不是实体模型中的某些要求? - Alfred Jones
+1 - 很棒的回答!我在大学实习期间曾经短暂地从事保险系统工作,虽然我所做的工作中从未遇到过这种情况,但这个解释非常有道理。感谢您的回答,@Joel! - JasCav

5
真正的一对一关系在现实世界中很少出现。这种类型的关系通常是为了绕过数据库管理软件的某些限制而创建的,而不是为了模拟真实世界的情况。在Microsoft Access中,当您必须将表拆分为两个或多个表时,可能需要使用一对一关系,因为出于安全性或性能方面的考虑或者由于每个表的列数限制为255列。例如,您可以将大多数患者信息存储在tblPatient中,但将特别敏感的信息(如患者姓名、社会保障号码和地址)放入tblConfidential中(参见图3)。与tblPatient相比,访问tblConfidential中的信息可能更加受限制。作为第二个例子,也许您只需要定期传输大型表的一部分到其他应用程序。您可以将表拆分为传输和非传输部分,并在一对一关系中将它们连接起来。 这是《关系数据库设计基础》一书中的引用。

这里有一个在SO上的相似问题

我认为使用1:1的另一个原因是,如果你有一张有很多列的表格,并且只有其中几列涉及非常频繁和需要快速查询的数据,那么我会将其分成两个相关的1:1表格,在其中一个轻量级表格上进行查询并获得良好的性能,但仍然可以通过简单的连接轻松地获得与其相关的其他数据。


1
难道不是通过视图来控制安全性和机密性吗?实际上,这不是首选方法吗?然而,列限制听起来像是一个真正的限制,只有使用1:1才能避免。 - Alfred Jones
我同意您关于安全和保密性的看法,也许那篇文章没有最好的例子,但我绝对可以理解有时您希望某些相关数据因为某种原因完全分离,比如出于法律考虑 - 比如股票信息以防止内幕交易(我有朋友实际上见过这种分离情况),或者医疗方面(请参见Joel的回答)等。 - richard
我给了你一个赞(我想现在我可以这样做),而且我希望我可以声称是两个答案的作者,但我认为Joel Coehoorn更是我寻求的一个更具体的例子。 - Alfred Jones
1
实际上,1:1关系并不罕见,但大多数Microsoft Access开发人员似乎对超类型和子类型知之甚少。例如,请参阅此SO问题的被接受答案:https://dev59.com/_G445IYBdhLWcg3wO3xu - Mike Sherrill 'Cat Recall'
@catcall:我认为重点是它们在现实关系中不常见,但它们被用于数据建模中,有时甚至经常使用,原因并非定义关系。 - richard

2

我认为表格设计应该考虑到领域背景。如果这些列形成了两个不同的实体,它们就不应该混在一个表中。从我的经验来看,1:1关系往往会随着时间的推移演变成1:n关系。

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

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


0

如果X与Y有1:1的关系,Z也与Y有1:1的关系,则将Y抽象为共享表而不是在X和Z中重复会很有用。

编辑:一个现实世界的例子是客户,公司和地址。客户和公司之间可以有N:N的关系。但是客户和公司都与地址有1:1的关系。一些地址行可能与客户和人员都相关。


但是这是否意味着X与Z之间存在1:1的关系,因此它们可以一起生活? - Joel Coehoorn
它使得X和Z可以间接相关,但这不是必需的。请参考我的编辑以获得更实际的例子。 - Robert Levy

0
首先,因为他们在谈论Access(Jet,Ace等),感谢@Richard DesLonde的发现,那么他们可能在谈论1:0..1关系。我认为在Access中真正的1:1关系是行不通的,因为它没有推迟约束的机制,也不能在SQL PROCEDURE中执行多个语句。大多数Access从业者满足于使用1:0..1关系来模拟真正的1:1关系,所以我猜作者们满意于非正式地使用术语“1:1”来指代两者。
当然,在现实世界中,1:1和1:1..0关系很常见。我认为他们试图传达一个(有效的)观点,即一些1:1和1:1..0关系是为了商业目的而在数据模型中发明的。
考虑一个“自然人”(即人类)和一个“公司”。他们没有共同的属性(当然,两者都有一个“名称”,但它们的域不同,例如,“自然人名称”具有“姓氏”,“名字”和“头衔”等子原子域)。

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

数据模型可以在高层次上进行“拆分”,从而产生非常相似的表格对,例如“自然人官员”和“公司官员”,“自然人官员自然人代表”和“公司官员自然人代表”等。

然而,另一种方法是使用虚构的实体类型来建模共同的属性和关系。例如,“自然人”和“公司”都可以被视为“法人”(附注:在法律上确实存在“法人”这个概念,但这是否意味着它在现实世界中也存在?!)

因此,我们可以为“法人”设置一个超类表,并分别为“自然人”和“公司”设置子类型表。 “官员”表将引用“法人”表。所有后续关系表都可以引用“官员”表,从这一点开始减少表的数量。
这种“子类化”方法存在实际问题。由于“自然人”和“公司”没有共同属性,因此它们没有共同的键,因此“法人”表需要具有人工键,这会带来所有相关问题,特别是如果需要在应用程序中公开。此外,由于“法人”,“自然人”和“公司”之间的关系真正是1:1,一些DBMS(如Access)将缺乏必要的功能来有效地实现它们,许多人将不得不将它们设为1:0..1。

-1

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

建模意义上1:1关系的一个很好的例子是员工和人之间的关系。您有一些数据的人,然后您在同一个人上有额外的属性,将其放在员工上。在面向对象编程术语中,将其视为继承类的一种好方法。Employee类继承自Person。实际上,许多ORM系统将在数据库中使用共享主键来建模1:1关系。


小心不要将“1:1”与“1:0或1”混淆。 - Joel Coehoorn
1:(1or0) 是一种1:1关系的情况。它是该关系的约束条件,但如果该关系存在,则仍然是1:1,并且在数据库中由于外键的存在变成了1:N。 - Scott
-1?真的吗。这是有效的。重要的是要知道建模与实际数据库中的内容是不同的。 - Scott
没关系,可能是我表达不清楚或跑题了。请随意给我投反对票,也许我会获得“受同行压力徽章” :) - Scott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接