存储和查询无与伦比的多对多关系

时间:2014-03-30 21:02:57

标签: sql database

我遇到过一个包含以下关系的数据库模式:

人(身份证,姓名) 朋友(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查询更改两个记录或依赖触发器来保持一致性会更好吗? / p>

1 个答案:

答案 0 :(得分:1)

好吧,在大多数数据库中,我可能会为Friends表寻找一行,其中包含以下两个条件:

  • id1上的唯一索引,id2
  • 检查id1<的约束ID2

但是,在MySQL中,您无法实现检查约束。因为您必须使用触发器,所以您可能还有插入/更新/删除触发器来管理重复的行。

两种方法都有优点和缺点。例如,对于第一个,您需要注意插入值的排序。或者,您需要一个触发器。或者,我通常会做的是,有一个存储过程包装数据库更改并负责正确的插入顺序。并且,获取X的所有朋友需要更复杂的查询。

第二种方法使用更多空间,这可能很麻烦。但是,它更容易回答诸如"谁是你朋友的朋友等问题。但是插入和更新会产生更多的开销。

最后,它实际上取决于您希望运行哪种查询。