关系数据库:以不同的解释重用同一张表

Posted

技术标签:

【中文标题】关系数据库:以不同的解释重用同一张表【英文标题】:Relational Database: Reusing the same table in a different interpretation 【发布时间】:2021-09-10 21:33:56 【问题描述】:

问题描述

我目前正在从事一个需要关系数据库进行存储的项目。 在考虑了一段时间的数据及其关系后,我遇到了一个非常重复的问题:

我遇到了实体 A 的通用数据模式,其中包含一些字段,例如名称、描述、值。该实体与实体 B 在多个 n-1 关系中连接。所以实体 B 在关系 rel1 中有 n 个实体 A,在关系 rel2 中有 n 个实体 A。

现在我正在尝试将此数据模型分解为关系数据库(例如 Postgres、mysql)的模式。 经过一番研究,我还没有真正找到解决这个特定问题的“最佳”解决方案。

到目前为止我发现了一些类似的问题:

*** DBA Stackexchange

我的想法

所以我想到了可能的解决方案,我将在这里介绍:

1。重复表

实体 B 到实体 A 的关系对它有一定的意义。因此可以创建多个表(每个关系 1 个)。这将解决所有直接问题,但实质上是重复表,这意味着现在必须将更改反映到多个表(例如新列)。

2。引入类型列

我只能说“实体 B 与 n 个实体 A 相连”,而不是多个关系。此外,我将添加一个类型列,然后告诉我 A 属于哪个关系实体。我不确定这是如何用 Spring-Hibernate 等常见 ORM 表示的,以及这是否会引入我目前不知道的其他问题。

3。抽象实体A的共同属性

另一种选择是创建一个 ADetails 实体,它捆绑了实体 A 的所有属性。 然后,我将创建两个实体,它们代表每个关系,并以一对一的关系连接到 ADetails 实体。这将解决外键的解释问题,但可能开销太大。

我的问题

在中大型项目的背景下,这些解决方案是否可行? 是否有某些缺点可以排除一种特定方法? 还有其他(更好的)我没有想过的选择吗?

感谢您对此事的任何帮助。

编辑 1 - PPR(个人-政党-角色)

感谢 AntC 的建议。 PPR Description

我认为所描述的情况符合我的问题。 让我们分解一下:

实体 B 是一个事件。对于给定的参与者,只有一个事件可以使这更容易。所以从事件到参与者的关系是 1-n。

实体 A 可以描述为组、人员、组织,但考虑到我的情况,它们都具有相同的属性。因此,将它们分成单独的表感觉是错误的想法。

用类图说明情况: 一个事件(实体 B)包含 n 个组(实体 A)、n 个人员(实体 A)和 n 个组织(实体 A)。

如果我理解正确,建议如下:

在我的例子中,事件和参与者之间的关系是 1-n RefRoles 表代表 ParticipantType 列,该列描述参与者所属的关系(例如,它是客户还是事件服务的一部分) 因为我所有的组、人员和组织都具有相同的属性,所以此时唯一需要的表是参与者表 如果将来有个别属性,我会引入一个新表(例如 People),以 1-1 关系引用参与者。 如果要添加多个表,则多个1-1关系的外键是互斥的(因此参与者只能有一个Group/Person/Organization)

AntC 和 Christian Beikov 提出的解决方案

拆分表确实有意义,同时将公共属性保留在一个表中。 目前没有单独的属性,但不再需要类型列,因为可以使用外键来查看实体属于哪个关系。

我为此创建了一个小例子:

一个活动存在 3 种类型(以前的类型列)人员:工作人员、VIP、访客 公共属性以 1-1 关系映射到 person 表。 为简单起见:每个人(员工、贵宾、访客)只能参加一个活动。 (在更高级的例子中是 n-m-relationship)

数据库架构如下:

在我看来,这种方法比类型列要好。 它还解决了以后必须根据应用程序中的实体类型来解释实体的问题。也可以在 ORM (see this question) 中解析类型列,但如果您使用的 ORM 不支持解析,这种方法可以避免麻烦。

【问题讨论】:

这是一个非常高级的q。你能说一下A, B是什么以及它们之间关系的本质吗?我想你可能在谈论 PPR(Person-Party-Role)结构——例如,同一个人可以是客户、供应商、员工、代理、其中一个的家庭成员等中的任何一个。databaseanswers.org/data_models/parties_roles_and_customers/…跨度> 感谢您的建议。我添加了一些说明(参见编辑 1)。 我想你已经开始了。您可能需要一个桥接表 Person-event-role,请参阅此答案:***.com/a/68171353/2840542。与该答案不同,您可能将同一个人以不同的角色链接到同一事件(桥中的多个记录),然后桥接表的事件角色形成其键。 【参考方案1】:

IMO,因为您已经对这些对象使用了专用术语,它们可能会出现分歧,之后拆分表是相当多的工作,在代码方面也是如此,所以我建议您从一开始就映射专用实体/表。

【讨论】:

感谢您的回答。我根据您在原始帖子中的回答添加了一个解决方案。你能确认这是否是你的意思吗?对我来说,解决这个问题似乎是正确的想法。

以上是关于关系数据库:以不同的解释重用同一张表的主要内容,如果未能解决你的问题,请参考以下文章

查询获取同一张表中1:N关系的数据

使用 Android 房间数据库在同一张表中的一对多关系

如何渴望对同一张表加载多个belongsTo关系?

ON CASCADE DELETE 对同一张表之间的多对多关系

Laravel 定义同一张表的多对多关系

同一张表上的多个关系