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

What is the best database structure to quickly fetch friends of friends in a large dataset?

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

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

好友Table

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

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

互动次数Table

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

现在,当用户访问产品页面时,他们可以看到与该产品互动过的好友。这很容易计算!

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

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

提前致谢。

坦率地说,我不明白为什么要在 Dynamo 中存储这些关系数据。 user_id 到朋友 table 正在表达一种关系,最好在关系数据库结构中建模。通过在 table.

上使用自连接,在这种数据存储中确定朋友的朋友变得微不足道。

table 可能看起来像这样(假设 "friends" 是您的示例数据中显示的双向关系)

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

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

这在查询朋友的朋友时变得很重要,因为您希望能够简化为单个可索引查询。换句话说,您不需要潜在地查询 table 两次来查看每个方向的关系 - 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。

使用 table 时,您需要确保关系 inserts/delete 在一次影响 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)