mysql - 在mysql中代表 "linked"联系人

标签 mysql database database-design

我正在尝试确定在现有 mysql 数据库中表示“链接”联系人(人员)概念的最佳方式。让我解释一下这意味着什么:

我有一张包含不同联系人的表,每个联系人都有一个 ID。我有另一个表,其中包含一个联系人可以属于的不同时间段。每个时期也有一个ID。联系人和期间之间存在 N:1 关系。我希望能够表示不同时期的两个(或更多)联系人实际上是同一个人(出于分析目的)。因此,如果链接了两个联系人,则出于分析目的应将他们视为一个联系人。例如,我可能想表示联系人 1 和 3 是同一个人。

Existing Schema

困难在于为两个以上的联系人(例如联系人 1、3 和 4)表示“链接”的概念。如果只有两个,我可以简单地有一个表,其中包含代表连接的两列。但是,由于可能有三个链接的联系人(或者任何数量,真的),这不是开箱即用的。

目前我想到了两种可能的解决方案:

1) 有一个包含两列的表(我们称之为 linked_contacts),每个列对应一个联系人 ID。这将代表一个连接。如果有超过 2 个链接的联系人,则将连接添加到其中一个链接的联系人。这样做的好处是在链接中添加另一个联系人的成本很低。缺点是,为了获得链接中的所有联系人,我基本上必须通过对每个连接进行查询来构建图表。

Linked Contacts Option 1

2) 仍然有包含两列的 linked_contacts 表。将新联系人添加到链接时,为新联系人和预先存在的联系人之间的每个连接生成一个新行。好处是我可以在单个查询中获取特定联系人的所有链接联系人。缺点是 table 更大。

Linked Contacts Option 2

附加说明

  • 预计不会有超过 2 个链接联系人的链接,但我愿意支持超过 2 个。
  • 检索此数据的主要用例是获取链接到特定联系人的所有联系人。
  • 从链接中删除联系人的可能性很小。将联系人添加到链接会更常见。
  • 检索性能是主要因素,因为我将在每个联系人页面上显示哪些联系人链接到特定联系人。

我倾向于选项 2,以便在给定特定联系人的情况下轻松/快速地检索链接中的所有联系人。是正确的方法吗?还有其他我应该考虑的因素吗?我也对其他设计策略持开放态度!

最佳答案

我认为“链表”是对您的要求的错误抽象。

如果需要在数据库中表示“人”的概念,那么直接表示就可以了,作为自己的表。例如:

enter image description here

同一个人的所有联系人共享同一个 PERSON_ID,这隐式地将他们联系在一起。

实际上,您将 CONTACT 变成了 PERSON 和 PERIOD 之间的“连接”(又名“链接”)表,这是建模多对多关系的标准方法。然后,您可以轻松找到其联系人属于给定时间段的所有人员,类似于此:

SELECT DISTINCT PERSON_ID
FROM CONTACT
WHERE PERIOD_ID = <whatever>

而且由于在 {PERIOD_ID, PERSON_NO}1 上有一个索引,这个查询可以通过简单的索引范围扫描来满足,这非常快 2.

如果您需要获取人员的其他字段,您也可以轻松地使用 PERSON 表加入,和/或如果您需要那里的其他字段,则使用 PERIOD。


1在 UNIQUE 约束下隐式创建,由上图中的 U1 指示。

2 顺便说一句,您可能还需要一个“相反”方向的索引:{PERSON_ID, PERIOD_ID},以满足搜索给定人员联系人的需求。

关于mysql - 在mysql中代表 "linked"联系人,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20821001/

相关文章:

database - 哪些数据库可以与 Chrome 扩展一起使用

python - Django:save() vs update() 来更新数据库?

mysql - 我应该规范化(合并)两个相似但不相同的表还是将它们分开?

mysql - 是否可以有一个表链接到一个使用外键链接回第一个表的表?

mysql - 当我尝试在多对多关联表上设置 2 个外键时,为什么会收到此错误消息? "Foreign key constraint is incorrectly formed"

database - 在数据库列中存储分隔列表真的那么糟糕吗?

mysql - jpaRepository 出现死锁

mysql - 比较不同表的聚合函数

mysql - JOIN 2个字段的表

mysql - 我的 SQL 查询获取共同/ friend 关注者