一对多和多对一关系的区别
Posted
技术标签:
【中文标题】一对多和多对一关系的区别【英文标题】:Difference between one-to-many and many-to-one relationship 【发布时间】:2011-06-03 20:31:33 【问题描述】:一对多和多对一关系的真正区别是什么?它只是颠倒的,有点?
除了这个主题之外,我找不到任何关于这个主题的“简单易懂”的教程:SQL for Beginners: Part 3 - Database Relationships
【问题讨论】:
这是完美的解释:en.wikipedia.org/wiki/Many-to-many_(data_model) @RobertPitt 多对多文章与该问题有何关联?你可能更愿意说en.wikipedia.org/wiki/One-to-many_(data_model) 【参考方案1】:是的,反之亦然。这取决于实体存在于关系的哪一侧。 例如,如果一个部门可以雇佣多名员工,那么部门与员工之间是一对多的关系(一个部门雇佣许多员工),而员工与部门之间的关系是多对一的(多个员工在一个部门工作)。
更多信息关于关系类型:
Database Relationships - IBM DB2 documentation
【讨论】:
恐怕不拍戏! (不确定,但)我认为顺序代表依赖!不是吗??例如,用户到角色可能是一对多但不是多对一,因为无法获得使用该角色的用户的引用!这有意义吗? 现在可以database relationships 吗? 但是如果一名员工只能在一个部门工作怎么办?嗯?没有这样的多对一。 这是正确的,但我相信它需要一些进一步的解释,在技术方面的理由。开发人员必须了解 RDBMS 与 ORM 和对象关系 DBMS 的区别。看我的回答。【参考方案2】:来自page about Database Terminology
表之间的大多数关系是一对多的。
例子:
一个区域可以成为许多读者的栖息地。 一个读者可以有多个订阅。 一份报纸可以有多个订阅。多对一关系与一对多关系相同,但视角不同。
许多读者住在一个区域。 许多订阅可以是同一个阅读器。 许多订阅都是针对同一份报纸的。
【讨论】:
【参考方案3】:一对多和多对一关系的真正区别是什么?
这些术语之间存在概念上的差异,应该可以帮助您可视化数据,并且应该完全理解生成的架构中可能存在的差异。不过,主要区别在于视角之一。
在一对多关系中,本地表的一行可能与另一个表中的许多行相关联。在SQL for beginners 的示例中,一个Customer
可能与多个Order
s 相关联。
在相反的多对一关系中,本地表可能有许多行与另一个表中的一行相关联。在我们的示例中,许多Order
s 可能与一个Customer
相关联。这种概念上的差异对于心理表征很重要。
此外,支持关系的模式在Customer
和Order
表中的表示方式可能不同。例如,如果客户有id
和name
列:
id,name
1,Bill Smith
2,Jim Kenshaw
然后,为了将Order
与Customer
关联起来,许多SQL 实现会在Order
表中添加一个列,该列存储关联Customer
的id
(在此架构customer_id
中:
id,date,amount,customer_id
10,20160620,12.34,1
11,20160620,7.58,1
12,20160621,158.01,2
在上面的数据行中,如果我们查看customer_id
id 列,我们会看到Bill Smith
(customer-id #1) 有两个与他关联的订单:一个是 12.34 美元,一个是 7.58 美元。 Jim Kenshaw
(客户 ID #2)只有 1 个订单,价格为 158.01 美元。
需要意识到的重要一点是,通常一对多关系实际上不会将任何列添加到作为“一”的表中。 Customer
没有额外的列来描述与Order
的关系。事实上,Customer
也可能与ShippingAddress
和SalesCall
表具有一对多关系,但没有向Customer
表添加其他列。
但是,对于要描述的多对一关系,通常会将id
列添加到“多”表中,该列是“一”表的外键——在本例中为 @ 987654348@ 列添加到Order
。要将 12.34 美元的订单 #10 关联到 Bill Smith
,我们将 customer_id
列分配给 Bill Smith
的 id 1。
但是,也可以有另一个表来描述Customer
和Order
关系,因此不需要向Order
表添加额外的字段。除了将customer_id
字段添加到Order
表之外,还可以有一个包含Customer
和Order
的键的Customer_Order
表。
customer_id,order_id
1,10
1,11
2,12
在这种情况下,one-to-many 和 many-to-one 都是概念性的,因为它们之间没有架构更改。哪种机制取决于您的架构和 SQL 实现。
希望这会有所帮助。
【讨论】:
一般情况称为包含依赖。外键约束是最常见的包含依赖类型,但并非所有包含依赖都涉及外键。 both 表中始终存在一个或多个公共属性(“引用”)。在“一个”方面,这些属性称为候选键。在“多”方面,它们可能是外键。术语“一对多”或“多对一”可以应用于涉及至少一个候选键的任何包含依赖项,而不必暗示哪一方可能是可选的。 有趣的@sqlvogel。在 Java 中,javax.persistence.OneToMany
与 ManyToOne
不同。您是说它们是同义词还是仅取决于实施?我的回答不正确吗?
问题是关于关系数据库和 SQL,而不是 Java。也许您对 Java 的看法是正确的。
我以@sqlvogel 为例。你是说“一对多”和“多对一”是同义词吗?
我的意思是,这是从不同的角度描述完全相同关系的两种方式。同理,“A 是 B 的子集”与“B 是 A 的超集”的含义相同。【参考方案4】:
SQL
在SQL中,只有一种关系,叫做Reference。 (您的前端可能会做一些有用或令人困惑的事情 [例如在某些答案中],但这是另一回事。)
一个表中的外键(引用ing表)引用 另一个表(referenced表)中的主键
在 SQL 术语中,Bar 引用 Foo 不是反过来
CREATE TABLE Foo (
Foo CHAR(10) NOT NULL, -- primary key
Name CHAR(30) NOT NULL
CONSTRAINT PK -- constraint name
PRIMARY KEY (Foo) -- pk
)
CREATE TABLE Bar (
Bar CHAR(10) NOT NULL, -- primary key
Foo CHAR(10) NOT NULL, -- foreign key to Foo
Name CHAR(30) NOT NULL
CONSTRAINT PK -- constraint name
PRIMARY KEY (Bar), -- pk
CONSTRAINT Foo_HasMany_Bars -- constraint name
FOREIGN KEY (Foo) -- fk in (this) referencing table
REFERENCES Foo(Foo) -- pk in referenced table
)
由于Foo.Foo
是主键,它是唯一的,Foo
的任何给定值只有一行
由于Bar.Foo
是一个引用,一个外键,并且上面没有唯一索引,所以Foo
的任何给定值可以有很多行
因此Foo::Bar
是一对多的关系
现在您可以感知(查看)相反的关系,Bar::Foo
是多对一的
Bar
行,它引用的只有一个 Foo
行
在 SQL 中,这就是我们所拥有的。这就是所有必要的。
一对多和多对一关系的真正区别是什么?
只有一种关系,因此没有区别。感知(从一个“端”或另一个“端”)或向后阅读,不会改变关系。
基数
基数首先在数据模型中声明,这意味着逻辑和物理(意图),然后在实现中(实现的意图)。
一对零对多 在 SQL 中,(以上)就是所有必需的。
一对多 您需要一个 Transaction 来强制执行引用表中的那个。
一对零对一
你需要在Bar
:
CONSTRAINT AK -- constraint name
UNIQUE (Foo) -- unique column, which makes it an Alternate Key
一对一 您需要一个 Transaction 来强制执行引用表中的那个。
多对多
在物理级别没有这样的事情(回想一下,SQL 中只有一种类型的关系)。
在建模练习的早期逻辑级别,方便绘制这样的关系。在模型接近实现之前,最好将其提升为仅使用可以存在的东西。这种关系可以通过在物理 [DDL] 级别实现关联表来解决。
【讨论】:
@Martijn Peters。我可以对其进行编辑以符合行为准则。但是您也删除了(a)解释,和(b)事实证明。我该怎么办? 找到一种不同的方式来表达这些事情,而不是诉诸咆哮、辱骂和诽谤任何人的智力或职业行为。专注于技术,而不是可能会或不会错的人。【参考方案5】:没有区别。这只是语言和偏好的问题,你以哪种方式陈述这种关系。
【讨论】:
在概念上以及生成的模式上肯定存在差异。看我的回答:***.com/a/37954280/179850 @Gray。不,那里没有。您的答案不仅不正确,而且让初学者(提出这个问题的人)感到困惑。【参考方案6】:一对多和多对一在多重性方面相似,但在方面(即方向性)方面不相似。
实体类之间关联与表之间关系的映射。有两类关系:
-
多重性(ER 术语:基数)
-
方向性:不会影响映射,但会影响我们访问数据的方式。
【讨论】:
关系数据库中没有“方向性”。每个关系都有两个“端”:引用(被引用的表)和引用(执行引用的表)。 SQL/DML 允许以任何你想要的方式引用任何表……一侧……另一侧……两侧……没有两侧。 @PerformaceDBA - 如果关系有外键约束,那么就有方向性, @Jason210 1) 在 SQL DDL 中,要建立关系,必须指定 FOREIGN KEY 约束。因此,所有关系都是 FK 约束。 2)那是在物理DDL级别,忽略逻辑(这是问题)。 关系模型是合乎逻辑的。从逻辑上看,在编写 SQL DML 时,关系有两个“端”,不限于 DDL 声明的任何内容。 了解更多relationaldbdesign.com/database-design/module6/…【参考方案7】:第一个问题的答案是:两者都相似,
第二个问题的答案是:一对多 --> 一个 MAN(MAN 表)可能有多个妻子(WOMEN 表) 多对一 --> 多个女人娶了一个 MAN .
现在,如果您想将此关系与两个表 MAN 和 WOMEN 关联,则一个 MAN 表行可能与 WOMEN 表中的行有许多关系。希望清楚。
【讨论】:
投反对票,你应该想出一个比一夫多妻制更合适的例子【参考方案8】:这是一个很好的问题,根据我的经验,在 ERD 图和关系数据库中暗示了方向。在 RDBMS 中,您总是定义多对->一(平凡的一对->一)关系。关系的多方,也就是孩子,引用了一方,也就是父母,您可以使用外键约束来实现这一点。从技术上讲,您必须访问索引,获取一侧的主键记录,然后访问该记录以获取更多信息。
除非我们谈论对象关系 DBMS,例如 Postgres、Intersystems Cache 等,否则您不能反过来这样做。这些 DBMS 允许您定义两个实体(表)之间的双向关系。在这种情况下,以另一种方式访问记录,即 One--To-->Many 是通过使用引用数组(子项)来实现的。在 ORM 中,您的类相互引用的方式与我们在此处描述的方式相同。
警告:IT 市场中的大多数 RDBMS 都不是严格意义上的关系数据库管理系统,考虑空值、重复记录等,其中许多允许的功能破坏了关系的定义。
【讨论】:
商业 RDBMS SQL 平台(Oracle 除外)是关系型的。免费软件不是关系型(允许禁止的对象,例如循环引用),并且不符合 SQL。【参考方案9】:没有实际区别。考虑到您对问题的看法,如 Devendra 所示,只需使用最有意义的关系即可。
【讨论】:
@Gray。不,那里没有。您的答案不仅不正确,而且让初学者(提出这个问题的人)感到困惑。【参考方案10】:一对多和多对一关系是指相同的逻辑关系,例如一个 Owner 可能有多个 Home,但一个 Home 只能有一个 Owner。
所以在这个例子中,所有者是唯一的,而房屋是众多的。 每个 Home 总是有一个 owner_id(例如外键)作为额外的列。
这两者在实现上的区别,是哪个表定义了关系。 在一对多中,所有者是定义关系的地方。例如,owner1.homes 列出所有拥有 owner1 的 owner_id 的房屋 在多对一中,家庭是定义关系的地方。例如,home1.owner 列出了 owner1 的 owner_id。
我实际上不知道在什么情况下您会实施多对一安排,因为您已经知道 owner_id,这似乎有点多余。也许它与删除和更改的清洁度有关。
【讨论】:
【参考方案11】:---一对多---父母可以有两个或更多的孩子。
---多对一---这三个孩子可以有一个父母
两者相似。这个可以根据需要使用。如果您想为特定的父母寻找孩子,那么您可以选择一对多。或者,想给双胞胎找父母,可以选择Many-To-One。
【讨论】:
【参考方案12】:对于这种关系,我能给出的最简单的解释是使用evendra D. Chavan's
answer。
利用部门和员工的关系
一个部门可以有多个员工,所以从员工方面来说,是one-to-many
关系,从部门方面来说是many-to-one relationship
但是如果一个员工也可以属于多个部门,我们也可以从员工方面说现在是many
而不是one
,所以关系变成many-to-many
换句话说,一个简单的理解是,如果可以从双方查看one-to-many
,我们可以说关系是many-to-many
那就是如果;
one-to-many
)
一个部门可以有很多员工 (one-to-many
)
【讨论】:
【参考方案13】:一对多的父类包含n个子类,所以它是一个集合映射。
多对一有n个孩子包含一个父母,所以它是一个对象映射
【讨论】:
这个答案很好,并且有其他信息不明白为什么它被否决了,在单向上下文中,一对多和多对一不会提供相同的代码质量,具体取决于用户体验:如果你需要获取一组相关的数据,因此一对多更明智,如果您不需要选择语句,其中某些条件很好,因为该集合在地图中,但是如果用户不需要获取数据集和对每一行都感兴趣,因为它是一个独特的期望实例,所以多对一是更明智的选择 这可能是一个很好的答案,但它们并不相同:多对一有一个包含 n 个子级的父类,一对多有多个父级到一个子级。在 SQL 中,它可能没有区别,因为多对一关系可以是全方位的,但在 Django 等框架中,这是一个主要问题,因为没有一对多关系和外键处理多对一关系只能自然地在一个方向上起作用,不能以同样的方式反过来使用。 @MohammedHousseynTaleb 所写的内容对于对象关系 DBMS 和 ORM 来说是正确的,请参阅我的答案以获得正当性。在没有适当证明你的行为合理的情况下将他降级是不公平的。以上是关于一对多和多对一关系的区别的主要内容,如果未能解决你的问题,请参考以下文章