在大型数据集中快速获取朋友的朋友的最佳数据库结构是什么?

时间:2015-10-01 18:26:38

标签: database database-design amazon-dynamodb backend amazon-rds-aurora

我们有1000万用户可以与150万种产品进行互动。

在dynamodb(NoSQL数据库)中,我们存储了这样的用户友谊:

朋友表

user_id    |    friends
1          |    [2, 3, 4]
2          |    [1,5]
3          |    [1, 4]
4          |    [1, 3, 5]
5          |    [2, 4]

在Amazon RDS(SQL数据库)中,我们进行了交互:

交互表

row  |   user_id   |   product_id
1    |      1      |      1
2    |      1      |      2
3    |      3      |      3
4    |      4      |      3

到目前为止,当用户访问产品页面时,他们可以看到与该产品进行过互动的朋友。这很容易计算出来!

但是,如果我们也想展示他们的朋友朋友呢?

为实现此目标而建模数据库的最佳方法是什么?我们可以完全改变数据库结构,做一些数据预处理等等。

提前致谢。

1 个答案:

答案 0 :(得分:3)

我坦率地说,为什么你不会在Dynamo中存储任何这种关系数据。 user_id到friends表表达关系,并且最好在关系DB结构中建模。通过在桌面上使用自联接,确定朋友的朋友在这种数据存储中变得微不足道。

该表可能如下所示(假设“朋友”是双向关系,因为它显示在您的示例数据中)

user_1    user_2
1         2
2         1
1         3
3         1
1         4
4         1
...

请注意,这是一个多对多连接表,其中每个朋友关系由两行描述(每个方向的关系)。

这在查询朋友的朋友时变得很重要,因为您希望能够简化为单个可索引的查询。换句话说,您不需要两次查询表以查看每个方向的关系 - user_1和user_2没有特定含义。

查询可能如下所示:

SELECT DISTINCT
    t2.user2
FROM table AS t1
INNER JOIN table AS t2
  ON t1.user_2 = t2.user_1
WHERE t1.user_1 = ?

?是有问题的用户ID。

使用表时,您需要确保关系插入/删除是原子的,一次影响2行。

可以通过以下查询实现插入:

INSERT INTO table (user_1, user_2) VALUES (1,2),(2,1)

删除可能看起来像

DELETE FROM table WHERE (user_1 = 1 AND user_2 = 2) OR (user_2 = 1 AND user_1 = 2)