更好的方式存储朋友和检索特定用户的朋友

时间:2013-07-05 14:04:41

标签: mysql database performance database-design

查询哪些mysql存储方法会更快(检索特定用户的朋友说@anyid):

Table: Friends

Columns: friend1 friend2

每个友谊和查询只插入一行

select friend1 
from FRIENDS 
where friend2=@anyid
UNION ALL
select friend2 
from FRIENDS 
where friend1=@anyid

OR

每个友谊插入两行(插入为friend1 friend2,然后插入交换的条目,例如1,2和2,1),然后简单地查询为

select friend2 from FRIENDS where friend1=@anyid

对我来说,似乎第二种方法会表现得更好,因为它只需要对单个列friend1和单个查询进行索引。第一种方法可能需要索引两列,并且需要运行两个子查询。但在某些帖子中,我看到人们声称第一种方法可能表现更好。 从正面来看,与第二种方法相比,第一种方法将占用一半的存储空间,这对于百万条记录来说会产生巨大的差异。

另外一件事是,它甚至需要为上述两种方法中的任何一种存储单独的relationship_idcreation_date。除了给我创建关系的时间或顺序之外我还能得到什么特别的好处,我想大多数人应该能够在没有它的情况下生活?

感谢您的回答!

1 个答案:

答案 0 :(得分:3)

对我而言,根本问题是:“数据库中有多少友谊?”如果只有A和B是朋友,则数字是“1”或“2”。这个答案决定了你如何理解友谊实体以及它应该如何实施。

这两种方法肯定存在差异。以第一种方式计算朋友数量:

select count(*)
from friends
where USERID in (friend1, friend2);

select count(*)
from friends
where USERID = friend1;

第二个可以更轻松地利用friend1上的索引,并且可以优化为比第一个更快。

另一方面,插入记录需要两倍的时间。找到朋友的朋友(等等)需要处理更多的数据,因此需要更多的处理时间。

友谊关系确实有其他特征,例如谁发起了请求(在第一种方法中通常是friend1)。或者请求和接受友谊的时间。这些额外信息表明了消除重复数据的第一种方法。

换句话说,关于数据结构的问题 - 就像几乎所有这些问题一样 - 都是通过你如何理解实体以及它们将如何被使用来回答的。