我遇到了一个包含以下关系的数据库模式:
人 ( 身份证, 姓名 )朋友 ( ID1, ID2 )
ID1 和 ID2 是 Person.ID 的外键
朋友是一种无方向的关系(即它是双向的)。在架构中,对于从 ID 123 到 ID 456 的给定友谊,它存储为两个元组:(123, 456) 和 (456, 123)。
在我看来,将单个概念实体存储在两个元组中是不好的:数据可能会变得不一致;并且数据集中存在重复。
除非我弄错了,否则应该可以对数据库做我们想做的所有事情,即使只有一个元组。在最坏的情况下,可以轻松重新创建表的版本:
SELECT *
FROM Friend
UNION
SELECT ID2 as ID1, ID1 as ID2
FROM Friend
所以我的问题是:存储无定向多对多关系的最佳实践是什么?为什么呢?
如果将信息存储在两个元组中是最好的执行方式,那么 INSERT INTO、UPDATE 和 DELETE 查询来更改这两个记录,还是依靠触发器来保持一致性会更好?
好吧,在大多数数据库中,我可能会在以下两个条件下为Friends
表选择一行:
- ID1、ID2 上的唯一索引
- 检查 ID1
但是,在MySQL中,您无法实现检查约束。 因为您必须求助于触发器,所以您也可以使用插入/更新/删除触发器来管理重复行。
这两种方法都有优点和缺点。 例如,对于第一个,您需要注意插入值的顺序。 或者,您需要一个触发器。 或者,无论如何,我通常会做的是拥有一个存储过程来包装数据库更改并处理正确的插入顺序。 而且,获取 X 的所有好友需要一个更复杂的查询。
第二种方法使用更多空间,这可能很麻烦。 但是,它更容易回答诸如"谁是朋友的朋友"之类的问题。 但是插入和更新的开销更大。
最后,这实际上取决于您要运行哪种查询。