gpt4 book ai didi

mysql - “多对二”关系

转载 作者:行者123 更新时间:2023-12-03 01:12:46 27 4
gpt4 key购买 nike

我想知道“多对二”的关系。 child 可以与两个 parent 中的任何一个联系,但不能同时与两个 parent 联系。有什么办法可以加强这一点吗?我也想防止 child 重复条目。

一个真实的例子是电话号码、用户和公司。一家公司可以有很多电话号码,一个用户可以有很多电话号码,但理想情况下,用户不应该提供与公司相同的电话号码,因为数据库中会有重复的内容。

最佳答案

这个问题表明您没有完全理解实体关系(无意粗鲁)。其中有以下四种(技术上只有 3 种)类型:

一对一
一对多
多对一
多对多

一对一 (1:1):
在这种情况下,为了符合规范化,或更常见的开放封闭原则,表格被分成两部分。

Normalisation合规性:您可能有一个业务规则,即每个客户只有一个帐户。从技术上讲,在这种情况下,您可以说客户和帐户都可以在同一张表中,但这违反了规范化规则,因此您将它们拆分为 1:1。

Open-Close principle合规性:客户表,可能有 ID、名字和姓氏以及地址。后来有人决定添加出生日期和计算年龄以及其他一些急需的字段的能力。这是一个过于简化的一对一示例,但它的主要用途是在不破坏现有代码的情况下扩展数据库。编写的许多代码(遗憾的是)与数据库紧密耦合,因此表结构的更改会破坏代码。添加像这样的 1:1 将扩展表以满足新的要求,而无需修改原始代码,从而允许旧代码继续正常运行,新代码可以利用新的数据库功能。

以这种方式使用 1:1 关系的规范化和扩展表的缺点是性能。通常在频繁使用的系统上,提高数据库性能的第一个目标是去规范化并将这些表合并到一个表中,并优化索引,从而消除使用连接和从多个表中读取的需要。规范化/去规范化既不是好事也不是坏事,因为它取决于系统的需求。大多数系统通常会在需要时开始规范化变回,但是如前所述,这种更改需要非常小心地进行,如果代码与 DB 结构紧密耦合,则几乎肯定会导致系统失败。即当您组合 2 个表时,一个不复存在,所有包含现在不存在的表的代码都将失败,直到它被修改(用 db 术语,想象一下将关系连接到 1:1 中的任何表,当您删除这些表时, 这打破了关系,因此必须对结构进行大量修改以进行补偿。不幸的是,在大多数情况下,这种糟糕的设计在 DB 世界中比在软件世界中更容易发现,而且您通常不会注意到出现问题在代码中直到它全部崩溃)除非系统使用 separation of concerns 正确设计心里。

它是您在面向对象编程中最接近继承的东西。但它并不完全相同。

一对多 (1:M)/多对一 (M:1):
这两种关系(为什么 4 变成 3)是最流行的关系类型。他们都是同一种关系,唯一改变的是你的观点。一个例子 一个客户有很多电话号码,或者很多电话号码可以属于一个客户。

在面向对象的编程中,这将被视为组合。它不是继承,但您是说一项由许多部分组成。这通常用类内部的数组/列表/集合等表示,而不是继承结构。

Many to Many (男:男):
这种与当前技术的关系是不可能的。出于这个原因,我们需要将其分解为两个一对多的关系,并使用一个“关联”表将它们连接起来。两个一对多关系的多方总是在关联/链接表上。

对于您的示例,说您需要多对多的人是正确的。因为二对多实际上是多(意味着不止一个)对多的关系。这是让系统正常工作的唯一方法。除非你打算研究relational calculus的领域找到一些允许这种情况的新型关系。

同样对于此类关系 (m2m),您有两种选择,要么在链接器表中创建一个复合键,以便字段组合成为唯一条目(如果您对数据库优化感兴趣,这是较慢的选择,但占用的空间较少)。或者,您使用自动生成的 id 列创建第三个字段并将其设为主键(对于数据库优化,这是更快的选择,但需要更多空间)。

在你上面的例子中......

A real world example would be phone numbers, users and companies. A company can have many phone numbers, a user can have many phone numbers, but ideally the user shouldn't provide the same phone number as the company as there would be duplicate content in the DB.



这将是与电话号码表作为公司和用户之间的链接器表的多对多关系。如前所述,为确保没有电话号码重复,您只需将其设置为主键或使用另一个主键并将电话号码字段设置为唯一。

对于这类问题,实际上取决于您如何表达它们。是什么导致您对此感到困惑,以及您如何克服这种困惑以查看解决方案很简单。将问题改写如下。首先询问是否一对一,如果答案是否定的,请继续。下一个问题是一对多,如果答案是没有继续前进。剩下的唯一其他选择是多对多。不过要小心,确保在继续之前仔细考虑了前两个问题。许多没有经验的数据库人员经常通过定义一对多和多对多来使问题复杂化。再一次,迄今为止最受欢迎的关系类型是一对多(我会说 90%),多对多和一对一分别将剩余的 10% 分成 7/3。但这些数字只是我个人的观点,所以不要引用它们作为行业标准统计数据。我的观点是在选择多对多之前要格外确定它绝对不是一对多。值得付出额外的努力。

所以现在要找到两者之间的链接器表,决定哪两个是你的主表,以及它们之间需要共享哪些字段。在这种情况下,公司和用户表都需要共享电话。因此,您需要制作一个新的电话表作为链接器。

一旦您确定这 3 种方法都不适合您,误会警告应立即显示。这应该足以告诉您,您只是没有正确表达关系问题。随着时间的推移,你会变得更好,但它是一项必不可少的技能,为了你自己的理智,真的应该尽快掌握。

当然,您也可以使用面向对象的数据库,该数据库将允许一系列其他关系,称为“层次”关系。如果你也想成为一名程序员,那就太好了。但是我不推荐这样做,因为当您开始寻找将各种类型的关系结合起来的方法时,它会让您头疼。特别是考虑到不需要太多,因为世界上几乎所有的数据库都只包含这 3 种类型的关系,除非它们是 super 特别的东西。

希望这是一个合理的答案。感谢您花时间阅读它。

关于mysql - “多对二”关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6790671/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com