【问题标题】:Reading reliably from a constantly appended-to table从不断附加到的表中可靠地读取
【发布时间】:2010-01-12 21:09:25
【问题描述】:

我有一个 Web 应用程序,其中一个功能是不断地将行附加到一个大表中。这些行大致如下所示:

id bigint not null primary key
visited datetime not null
ip_address
# Other fields

您可能已经猜到了,这是一个跟踪表。本表的用途 完全是仅追加的,也就是说,在行之后没有修改行 已插入。

但是,我们的数据量已显着增加,这已成为必要 单独对其他表进行统计处理,而不是查询 数据并立即计算。基本上我已经写了一个独立的程序 这大约是这样做的(伪代码)

while (true) {
    Select rows from tracking table where id > last_id
    Feed rows to stats processing thread
    last_id = max(id from rows)
    sleep some amount of time (~30sec is what I'm currently using)
}

但是,我担心我会丢失行。可能会出现 ID 空白,因为 在我从跟踪表中选择行时,一些行 ID 有 已保留,但这些事务中的数据尚未提交,并且在 下一个循环我已经转移到更新的 ID。

我一直想知道如何协调这一点,因为计算时缺少数据 stats 并不是一个真正的选择。

这是我一直在折腾的各种选项:

  1. 重新设计表或查询访问时间等内容

  2. 不要使用关系数据库,而是使用某种数据排队系统?

  3. 查询表的时间滞后,即 WHERE id > last_id AND 访问

也有可能有一个我没有考虑过的选项。哪个最好 查询表的方法,这样我就不会错过任何数据?

【问题讨论】:

    标签: mysql transactions innodb


    【解决方案1】:

    这是您可以执行此操作的一种方法(类似于您的 #2):

    1. 将您的数据复制到单独的“仓库”数据库。
    2. 执行 ETL,以便您的数据在您的仓库中更优化地标准化,以进行查询/统计分析。对于每种记录类型,添加一个附加列作为“状态”标志,指示您的分析引擎是否已读取记录。
    3. 让您的分析在读取记录后更新“读取”列。

    【讨论】:

    • 感谢您抽出宝贵时间回答 :) 我决定对您的回答实施一个变体。因为在存储和处理的数据之间具有低延迟是一个优先事项,所以我仍然会从原始表中读取(跳过复制和 ETL),但我会为分析引擎保留另一个表来记录它有哪个 id见过。
    猜你喜欢
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    相关资源
    最近更新 更多