0

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

喜欢这里:https ://stackoverflow.com/a/35784048/1624397

INSERT INTO RECOMMENDED_BOOKS (Book_id1, Book_id2) VALUES (1, 2)
INSERT INTO RECOMMENDED_BOOKS (Book_id1, Book_id2) VALUES (1, 3)

Book_id1, Book_id2...

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

自引用用户friendsWithMemyFriends.

如果我做类似的事情tag_id1tag_id2我要么被迫搜索两者之间是否存在关系,要么被迫保留冗余数据。

有没有替代的解决方案?

优选地,该解决方案与存储无关。

4

2 回答 2

1

如果我理解正确,您对对称关系有疑问,因为有两种方法可以表示任何一对关联的标签。两种方式记录都会导致冗余数据,例如(1, 2)表示与 相同的关系(2, 1)。在没有对称破坏规则的情况下仅记录两者之一,需要更复杂的查询,例如WHERE (tag_id1, tag_id2) IN ((1, 2), (2, 1))

诀窍是引入对称破坏规则,例如tag_id1 <= tag_id2。插入/更新数据时,您必须强制执行规则。如果您的 DBMS 支持检查约束,这很容易,如果不支持,您可以考虑使用触发器来做同样的事情。

这简化了查询 - 您可以对要搜索的参数进行排序,以便您只需搜索单个排列,例如(1, 2).

也许有一天,我们将拥有针对对称关系、树等具有优化存储引擎的 DBMS。

于 2018-01-07T19:07:14.550 回答
0

我不知道有一种方法可以解决没有数据冗余的多对多表在关系数据库中进行简单查询。

您可以作弊并创建一个在查询时复制数据的视图,它看起来像这样:

CREATE VIEW VW_Friends
AS
SELECT PersonID, FriendID
FROM Friends
UNION
SELECT FriendID, PersonID
FROM Friends

我相信这会很慢而且不是很直观,我通常不会推荐它,但这是一个可能的解决方案。

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

如果不是这种情况,并且您的写入次数多于读取次数 - 不要复制数据并且在两列上都使用查询的尴尬 SELECT。

我希望这有帮助。

于 2018-01-07T20:20:08.513 回答