在 Stack Overflow 等消息传递论坛中,存储数据以跟踪谁阅读了哪些消息的有效方法是什么?
如果有 m
条消息和 n
个用户,是否有可能出现小于 m
* n 的最坏情况
位?
最佳答案
我将使用经典的 READ_MESSAGES
表。
-----FK---------FK------------------------------------
| msg_id | user_id | read_timestamp | blah...
------------------------------------------------------
\========PK==========/
这将适用于多达一百万行左右。然后插入将变得很痛苦。如果我们使用像 MySQL 这样的东西,那么我们将需要一个人工的自增主键。
-------------------FK---------FK----------------------------------
| autoinc_pk | msg_id | user_id | read_timestamp | blah...
------------------------------------------------------------------
\=====PK=====/ \===UNIQUE=NOT=NULL===/
这将很好地捕获我们的数据,但可能不是查询的最佳选择。我们有两种可能的方式:
- 给定
消息 id
显示哪些用户或有多少用户已阅读它。SELECT msg_id, COUNT(user_id) FROM read_messages WHERE msg_id='123'
- 给定
user id
显示已阅读了哪些或多少条消息。SELECT user_id, COUNT(msg_id) FROM read_messages WHERE user_id='456'
当然,系统将需要执行两种类型的查询,但如果它执行一种类型的查询方式多于其他类型,那么我们可以调整设计以使这些查询更快一些。这是通过更改 UNIQUE-NOT-NULL
键中列的顺序来完成的。想法是在两列之外,将具有给定值的列放在第一位,换句话说,将 WHERE
子句中出现的列放在第一位。
因此,如果我们发现系统执行的 Type-1 查询多于 Type-2 查询,我们会将列排序为 {msg_id, user_id}
否则我们将其排序为 {user_id , msg_id}
.请记住,当我们对多列键执行 WHERE
查询时,第一列有利于速度。
如果我们确实发现我们的应用程序更喜欢一种类型的查询,我们可以更进一步,在 WHERE
子句中的列上水平分区/分片表。在 Cassandra 或 DynamoDB 等数据库中,它可能是分区键。
关于database - 跟踪谁阅读了哪些消息的良好数据库结构是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45384534/