首页 > 解决方案 > 在 SQL 数据库中将用户作为“别名”相互连接,而无需复制数据条目

问题描述

需要一点建议。我有一个项目将用户存储在数据库中,并确定更多两个或更多用户何时实际上是同一个人。因此,如果我让 Bob、Joe、Tom、Sam、Fred 和 Lucy 注册,后来发现(通过录取或其他方式)Joe、Tom 和 Lucy 实际上是同一个人,我想记录下来关系的方式是,如果我搜索其中任何一个,其他名称或“别名”也会出现,无论连接如何。

可以在不同的时间知道 Tom = Lucy,然后是 Joe = Lucy,或者存在 Joe -> Tom -> Lucy 的线性级数,但是如果我搜索 Lucy,Tom 和 Joe 都应该显示为连接或别名,并且反之亦然。

只是寻找有关用户表设置的想法,这将允许通过简单的搜索查询实现这一点,而无需使用手动填写的额外“别名”字段建立连接(即将连接用户的每个组合放入字符串领域作为一个坏例子)。子表关系是我目前正在考虑的地方。不确定如何以最佳方式进行而不生成重复的手动数据输入。

伪 SQL 很好。主要是想就如何最好地实现这一点产生想法。感谢您提前输入!

标签: sqldatabasepseudocode

解决方案


这本质上是一个连通组件问题。将数据视为无向图,其中顶点是人,边表示别名。我们希望找到连接的组件并在添加新边(别名)时更新它们。

我们可以有一个名称表,其中包含一个附加alias列,其值表示相应行所属的组件。最初,每个人都将在他们自己的组件中(alias最初将是唯一的)。当要建立say personA和之间的别名时,我们用(or )列的值更新组件中属于(or )的所有person的列。这将合并组件。BaliasBAaliasAB

CREATE TABLE persons (
 id INTEGER PRIMARY KEY,
 name varchar(100),
 alias INTEGER NOT NULL
)

INSERT INTO persons (id, name, alias)
VALUES (1, 'Bob', 1), (2, 'Joe', 2), (3, 'Tom', 3),
       (4, 'Sam', 4), (5, 'Fred', 5), (6, 'Lucy', 6)

-- Tom = Lucy
UPDATE persons
SET alias = (SELECT alias FROM persons WHERE name = 'Tom')
WHERE alias = (SELECT alias FROM persons WHERE name = 'Lucy')

-- Joe = Lucy
UPDATE persons
SET alias = (SELECT alias FROM persons WHERE name = 'Joe')
WHERE alias = (SELECT alias FROM persons WHERE name = 'Lucy')

-- linear progression of Tom = Lucy = Joe
-- Run the above queries one after another

-- Search for all alias of Tom

SELECT *
FROM persons WHERE alias = (SELECT alias FROM persons WHERE name = 'Tom')

这是一个带有查询工作示例的SQL Fiddle 。


推荐阅读