database - 跟踪谁阅读了哪些消息的良好数据库结构是什么?

标签 database algorithm

在 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===/

这将很好地捕获我们的数据,但可能不是查询的最佳选择。我们有两种可能的方式:

  1. 给定 消息 id 显示哪些用户或有多少用户已阅读它。 SELECT msg_id, COUNT(user_id) FROM read_messages WHERE msg_id='123'
  2. 给定 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/

相关文章:

java - 广度优先搜索 - Java

algorithm - 找到构成序列的最大子集

java - 给定一个排序整数数组,我如何找到是否存在一组总和为 K 的 3 个元素?

ruby-on-rails - 如何从模型在 Rails 3 中执行复杂的 Arel 查询

mysql - 数据库设计和规范化

php - MySQL 连接在 PHP 中有效,但在 ASP 中无效

algorithm - 在给定节点和坐标列表的情况下查找最近的节点

database - 防止 Django 在并发请求时将同一个对象多次保存到数据库

mysql - 如何使用sql数据库或mysql数据库。没有在database.yml中定义它

c# - 从一侧缩放多边形