Database design 无id编号的多对多自参考

Database design 无id编号的多对多自参考,database-design,rdbms,database-agnostic,Database Design,Rdbms,Database Agnostic,我想在两个标记实体之间建立一种关系,但我不喜欢在RDBMS数据库中处理这种关系的典型方式 就像这里: 图书编号1,图书编号2 或者另一个我正在寻找替代方案的“坏”例子(无论如何,在这种情况下是有意义的): 对用户好友的自引用我和我的好友 如果我执行类似于tag_id1和tag_id2的操作,我将被迫两次搜索两者之间是否存在关系,或者被迫保留冗余数据 有没有其他解决办法 最好是存储不可知的解决方案。如果我理解正确,您会遇到对称关系的问题,因为有两种方法可以表示任何一对关联的标记。双向记录会导致冗余

我想在两个标记实体之间建立一种关系,但我不喜欢在RDBMS数据库中处理这种关系的典型方式

就像这里:

图书编号1,图书编号2

或者另一个我正在寻找替代方案的“坏”例子(无论如何,在这种情况下是有意义的):

对用户
好友的自引用我
我的好友

如果我执行类似于
tag_id1
tag_id2
的操作,我将被迫两次搜索两者之间是否存在关系,或者被迫保留冗余数据

有没有其他解决办法


最好是存储不可知的解决方案。

如果我理解正确,您会遇到对称关系的问题,因为有两种方法可以表示任何一对关联的标记。双向记录会导致冗余数据,例如
(1,2)
表示与
(2,1)
相同的关系。如果没有对称性破坏规则,只记录其中一个需要更复杂的查询,例如((1,2)、(2,1))中的(
WHERE(tag_id1,tag_id2)


诀窍是引入对称性破缺规则,例如,
tag_id1我不知道有什么方法可以解决多对多表而不需要数据冗余,并且在关系数据库中有简单的查询

您可以欺骗并创建一个在查询时复制数据的视图,其外观如下:

CREATE VIEW VW_Friends
AS
SELECT PersonID, FriendID
FROM Friends
UNION
SELECT FriendID, PersonID
FROM Friends
我相信这将是缓慢的,不是很直观,我一般不会推荐它,但它是一个可能的解决方案

在您的位置上,我将使用冗余数据,因为这将针对选择数据进行优化,并且在大多数情况下,像这样的表将具有比写入多得多的读取

如果情况并非如此,并且您的写操作比读操作多,则不要重复数据,并且在两列上进行查询时进行笨拙的选择


我希望这会有所帮助。

Postgres特定,但有些替代方案也适用于其他DBMS:我建议您查看图形数据库以存储此类数据。它们就是为这个而设计的,可以很容易地处理这类问题。还允许高效地查询会阻塞关系数据库的复杂关系。@一个没有名字的马谢谢,我在NoSQL上为这个项目提供了类似的解决方案(数组,json)。但是现在,由于维护和性能的原因,需要太多的关系,迫使我们转向RDMBS。@JustinasMarozas谢谢,这就是我在开始项目之前的想法。然而,在分析了利弊之后,我得出结论,仅仅因为这个单一的非键(尽管确实经常使用)功能就使用Graph DB不足以改变一切。请检查我的答案,仅针对标签管理,它还不成熟,但对于启动新的解决方案非常有用。您可以轻松创建一个约束,以防止插入
(2,1)
,因为
(1,2)
已经存在
CREATE VIEW VW_Friends
AS
SELECT PersonID, FriendID
FROM Friends
UNION
SELECT FriendID, PersonID
FROM Friends