【问题标题】:Best practice reading newest rows from database从数据库中读取最新行的最佳实践
【发布时间】:2016-03-04 17:52:09
【问题描述】:

我有一张表,它非常频繁地存储我的用户的位置。我想经常查询这个表并返回我没有读过的最新行。

执行此操作的最佳做​​法是什么。我的想法是:

  1. 添加boolean 读取标志,查询所有结果为假,返回它们,然后全部更新。这可能会因额外的写入而减慢速度
  2. 在客户端保存最后读取行的id,查询大于这个的行。这里唯一的问题是我的客户可能会失去他们的位置
  3. 一些数据流

最终会有多个usersreaders 的位置,所以这不会有点规模

【问题讨论】:

    标签: mysql django postgresql


    【解决方案1】:

    如果您拥有的是一个存储多行数据的 SQL 数据库。我建议类似选项 2。

    我可能会做的是保留时间戳而不是 ID,并在其上创建索引(MSSQL 上的聚集索引或类似结构,以便新行按时间物理排序)。然后只需查询比这更新的任何东西。

    这确实存在“失去位置”的问题。如果客户端必须读取发布的每一行,那么我要么在处理后删除它们,要么在数据库中有一个标志来指示它们已被处理。如果客户端只需要重新开始读取当前数据,那么我会按照上面的方法做,但是用最近存在的行来初始化时间。

    如果您必须处理每条记录,而不仅限于数据库,那么您真正谈论的是消息队列。如果您需要能够处理后访问各个数据点,那么消息处理的一个步骤可能是插入数据库以供以后查询(除了对数据所做的任何事情)阅读)。

    按 cmets 编辑:

    如果在接收时不需要进行任何处理,但您只想定期更新数据,那么您可以采用保留上次接收时间或 ID 而不是删除数据的解决方案。在这种情况下,我建议不要在重新启动/重新连接时保留最后一个已知的 id/时间戳,因为您最终可能会无意中加载一堆数据。重新启动时将其重置为最大值。

    另一方面,当我做这样的事情时,我使用 MQTT 传输数据和“实时”更新取得了很大的成功。那是一个发布/订阅消息传递协议。您可以在后端有一个进程订阅并将数据转发到数据库,而经常需要数据的事物可以直接订阅数据流以进行实时更新。还有一个功能可以保留最后发布的消息并将其转发给新订阅者,这样您就不会一开始就完全空着。

    【讨论】:

    • 仅供参考,我强烈建议在处理完列标志后删除。仅仅是因为表会变得越来越大,所以有一个持续的进程读取/更新它会变得越来越慢。
    • 我需要历史数据的数据,所以我不想删除它。这是个问题吗?
    • 我也不需要处理每条记录,如果我失去了自己的位置并跳过一些很好。它只是用于在地图上为对象设置动画。
    • 如果您不介意丢失行的风险,选项 2 很好。具有较低 ID 的行可能会在具有较高 ID 的行之后提交,因此客户端会看到 1、2、3、5 - 然后在客户端获取它之后提交 4 次。客户下次会要求 > 5,所以它永远不会看到 4。
    猜你喜欢
    • 2016-08-26
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2013-09-16
    相关资源
    最近更新 更多