我前几天正在考虑规范化,而且我想到了,我想不出一个数据库中应该有1:1关系的时间.
名称:SSN?我将它们放在同一个表PersonID:AddressID?同样,同桌.
我可以提出一个很多或者很多的例子:很多(有适当的中间表),但从不是1:1.
我错过了一些明显的东西吗
1:1关系通常表示您出于某种原因已对较大的实体进行了分区.通常是由于物理模式中的性能原因,但是如果预期大量数据同时"未知"(在这种情况下,您有1:0),它也可能发生在逻辑方面.或1:1,但不多于).
作为逻辑分区的示例:您拥有关于员工的数据,但是当且仅当他们选择具有健康保险时,才需要收集更多的数据集.我会将有关健康保险的人口统计数据保存在不同的表中,以便更容易地进行安全分区,并避免在与保险无关的查询中拖运数据.
物理分区的一个示例是在多个服务器上托管的相同数据.我可以将健康覆盖人口统计数据保存在另一个州(例如人力资源办公室),主数据库可能只通过链接服务器链接到它...避免将敏感数据复制到其他位置,同时使其可用于(假设这里很少见)需要它的查询.
只要您的查询需要较大实体的一致子集,物理分区就会很有用.
一个原因是数据库效率.具有1:1的关系允许您拆分在行/表锁定期间受影响的字段.如果表A有大量更新,表b有大量读取(或者有来自另一个应用程序的大量更新),那么表A的锁定不会影响表B中发生的事情.
其他人提出了一个好点.安全性也可能是一个很好的理由,取决于应用程序等如何影响系统.我倾向于采取不同的方法,但它可以是限制对某些数据的访问的简单方法.在紧要关头拒绝访问某个表格真的很容易.
关于它我的博客文章.
稀疏.数据关系在技术上可以是1:1,但是对于每一行不必存在相应的行.因此,如果您有两千万行,并且有一些值仅存在于其中的0.5%,那么如果将这些列推出到可以稀疏填充的表中,则节省的空间非常大.
大多数高排名的答案为1:1关系提供了非常有用的数据库调优和优化原因,但我想只关注"野外"的例子,其中1:1关系自然发生.
请注意大多数这些示例的数据库实现的一个重要特征:没有关于1:1关系的历史信息.也就是说,这些关系在任何给定的时间点都是1:1.如果数据库设计者想要记录关系参与者随时间的变化,则关系变为1:M或M:M; 他们失去了1:1的性质.有了这个,这里有:
"Is-A"或超类型/子类型或继承/分类关系:此类别是指一个实体是另一个实体的特定类型.例如,可能有一个Employee实体,其属性适用于所有员工,然后是不同的实体,用于指示具有该员工类型唯一属性的特定员工类型,例如Doctor,Accountant,Pilot等.此设计避免了多个空值,因为许多员工不具备特定子类型的专用属性.此类别中的其他示例可以是Product as supertype,ManufacturingProduct和MaintenanceSupply作为子类型; 动物为超类型,狗和猫为亚型; 请注意,每当您尝试将面向对象的继承层次结构映射到关系数据库(例如在对象关系模型中)时,这就是表示此类场景的关系.
"老板"关系,例如经理,主席,总裁等,组织单位只能有一个老板,一个人只能是一个组织单位的老板.如果这些规则适用,那么您就拥有1:1的关系,例如一个部门的一个经理,一个公司的一个CEO等."老板"关系不仅适用于人.如果只有一家商店作为公司的总部,或者如果只有一个城市是一个国家的首都,则会发生同样的关系.
某些稀缺资源分配,例如一个员工一次只能分配一辆公司汽车(例如每辆卡车一辆卡车,每辆出租车司机一辆出租车等).最近一位同事给了我这个例子.
婚姻(至少在一夫多妻制是非法的法律管辖区内):一个人一次只能与另一个人结婚.我从一本教科书中得到了这个例子,当一家公司在员工之间记录婚姻时,这本书就是一对一合一关系的例子.
匹配预订:何时进行唯一预订,然后作为两个单独的实体履行.例如,汽车租赁系统可以在一个实体中记录预订,然后在单独的实体中记录实际的租赁.虽然这种情况可以替代地设计为一个实体,但是由于并非所有预订都得到满足,因此将实体分开可能是有意义的,并且并非所有租赁都需要预订,并且这两种情况都非常普遍.
我重复前面提到的警告,只有在没有记录历史信息的情况下,大部分都是1:1的关系.因此,如果员工在组织中更改其角色,或者经理负责不同部门,或者员工被重新分配车辆,或者某人丧偶并再婚,那么关系参与者可以改变.如果数据库不存储有关这些1:1关系的任何先前历史记录,则它们仍然是合法的1:1关系.但是,如果数据库记录历史信息(例如为每个关系添加开始和结束日期),那么它们几乎全部转变为M:M关系.
历史记录有两个值得注意的例外:首先,一些关系变化很少,通常不会存储历史信息.例如,大多数IS-A关系(例如产品类型)是不可变的; 也就是说,他们永远不会改变.因此,历史记录点没有实际意义; 这些将始终作为自然的1:1关系实现.其次,预订 - 租赁关系商店的日期分开,因为预订和租赁是独立的活动,每个活动都有自己的日期.由于实体具有自己的日期,而不是具有开始日期的1:1关系本身,即使存储了历史信息,这些也将保持为1:1的关系.
您的问题可以用多种方式解释,因为您的措辞方式.答复显示了这一点.
现实世界中的数据项之间肯定存在1:1的关系.毫无疑问."是一种"关系通常是一对一的.汽车是一种车辆.一辆车是一辆车.一辆车可能是一辆车.有些车辆是卡车,在这种情况下,一辆车不是汽车.几个答案解决了这种解释.
但我认为你真正要问的是......当存在1:1的关系时,表格是否会被分割?换句话说,你应该有两个包含完全相同键的表吗?在实践中,我们大多数人只分析主键,而不是其他候选键,但这个问题略有不同.
1NF,2NF和3NF的规范化规则从不要求将表分解(拆分)为具有相同主键的两个表.我还没有弄清楚,在BCNF,4NF或5NF中放置模式是否会导致两个具有相同密钥的表.在我的头顶,我会猜测答案是否定的.
有一个标准化程度称为6NF.6NF的规范化规则肯定会导致两个表具有相同的主键.6NF具有超过5NF的优势,可以完全避免NULLS.这对一些(但不是全部)数据库设计者很重要.我从来不打算将架构放入6NF.
在6NF中,缺失的数据可以由省略的行表示,而不是在某些列中具有NULL的行.
除了分割表的标准化之外还有其他原因.有时拆分表会带来更好的性能.对于某些数据库引擎,您可以通过对表进行分区而不是实际拆分来获得相同的性能优势.这样可以保持逻辑设计易于理解,同时为数据库引擎提供加速操作所需的工具.
我主要使用它们有几个原因.一个是数据变化率的显着差异.我的一些表可能有审计跟踪,我跟踪以前版本的记录,如果我只关心跟踪以前版本的10列中的5列,将这5列拆分到一个单独的表上,其上有一个审计跟踪机制更有效.此外,我可能有只写的记录(比如会计应用).您无法更改美元金额或其所用的帐户,如果您犯了错误,那么您需要创建相应的记录来编写调整不正确的记录,然后创建更正条目.我在表上有约束,强制它们无法更新或删除,但我可能有一些属于该对象的属性具有可塑性,这些都保存在一个单独的表中,没有修改的限制.我这样做的另一次是医疗记录应用.存在与访问相关的数据,一旦签名就无法更改,以及与签名相关的其他数据可以在签收后更改.在这种情况下,我将拆分数据并在锁定表上放置一个触发器,在签名时拒绝对锁定表的更新,但允许更新医生未注销的数据.
另一张海报评论说1:1没有被标准化,在某些情况下我会不同意,尤其是亚型.假设我有一个员工表,主键是他们的SSN(这是一个例子,让我们保留关于这是否是另一个线程的好键的辩论).员工可以是不同类型的,例如临时的或永久的,如果他们是永久性的,他们有更多的字段要填写,例如办公室电话号码,如果类型='永久',则该字段应该不为空.在第三个普通表格数据库中,该列应仅依赖于密钥,即雇员,但实际上它取决于员工和类型,因此1:1关系是完全正常的,在这种情况下是可取的.它还可以防止过度稀疏的表,如果我有10列通常填充,
我能想到的最常见的情况是你有BLOB的时候.假设您想要将大图像存储在数据库中(通常,不是存储它们的最佳方式,但有时约束会使它更方便).您通常希望blob位于单独的表中以改进非blob数据的查找.
就纯科学而言,是的,它们毫无用处.
在真实的数据库中,将一个很少使用的字段保存在一个单独的表中有时很有用:使用此字段加速查询并且仅使用此字段; 避免锁等
有时,将受限字段保留在只有某些用户才能访问的单独表中,而不是使用视图来限制对字段的访问.
我还可以想到你有一个使用继承的OO模型的情况,并且继承树必须保存到DB.
例如,你有一个Bird和Fish类,它们都继承自Animal.在你的数据库中你可以有一个'Animal'表,它包含Animal类的公共字段,Animal表与Bird表有一对一的关系,与Fish有一对一的关系表.
在这种情况下,您不必拥有一个包含许多可为空的列的Animal表来保存Bird和Fish属性,其中包含Fish-data的所有列在记录表示鸟时都设置为NULL.
相反,您在Birds-table中有一条记录,它与Animal表中的记录具有一对一的关系.
如果你有太多的信息,也需要1-1关系.表中的每条记录都有记录大小限制.有时表被分成两部分(主表中最常查询的信息),只是为了使记录大小不会太大.如果表格很窄,数据库在查询时也更有效.
它也是一种扩展已经投入生产的表的方法,其风险比"实际"数据库更改更少(感知).在遗留系统中看到1:1关系通常是在初始设计之后添加字段的良好指标.
在SQL中,不可能在两个表的两个表之间强制执行1:1关系(除非表是只读的).对于大多数实际用途,SQL中的"1:1"关系实际上意味着1:0 | 1.
无法在引用约束中支持强制基数是SQL严重限制之一."可延迟"约束并不真正重要,因为它们只是说某种程度上不强制执行约束的方式.