我们有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
到目前为止,当用户访问产品页面时,他们可以看到与该产品进行过互动的朋友。这很容易计算出来!
但是,如果我们也想展示他们的朋友朋友呢?
为实现此目标而建模数据库的最佳方法是什么?我们可以完全改变数据库结构,做一些数据预处理等等。
提前致谢。
答案 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)