【问题标题】:Inventory History - Version Control Style Approach清单历史 - 版本控制风格方法
【发布时间】:2014-03-07 17:51:13
【问题描述】:

情况

我正在为一个跟踪超过 200,000 个序列化设备的应用程序创建库存历史记录。目标是能够及时回顾并准确知道设备在 X 天的位置。

我认识到理想的情况可能是在项目立即更改时触发触发器以更新历史记录,但这将是一项非常大规模的任务,并且无法通过当前应用程序轻松实现。

考虑到这一点,我们决定每晚运行一个脚本,检查当前库存并将其存储到跟踪库存位置、状态等的inventory_history 表中。最初,我们试着每天都在历史中扑通扑通。 IE 每天插入 200,000 行,每 5 天产生超过 100 万条记录。我们发现这将在不到一年的时间内产生 GB 的数据。我提出的解决方案是在版本控制风格的历史中实现它。因此,与其每天插入 200,000 条记录,不如只插入已更改的记录。 (并为已删除的记录插入已删除的记录。)

问题

  • 这种方法有什么明显的问题吗?对于不是为历史设计的已构建应用程序,是否有更好的替代方法?
  • 如果这种方法很好,需要实施哪些我可能会遗漏的方法?目前我实现了以下场景:
    • 插入,如果不存在完全相同的值。
    • 如果当天未找到设备,则插入删除记录。
    • 选择时,使用历史搜索允许的最近日期按设备 ID 分组。 (如果我们想知道 2014 年 1 月 1 日的库存状态,不要选择之后发生的任何记录,而是将记录分组,以便显示的是最新的。)

备注

当我们查看历史记录时,有时我们想知道特定的设备,而有时我们想要当天的库存摘要报告。

【问题讨论】:

  • 您如何知道记录何时更改?库存表中是否有字段(例如 last_updated)?
  • 比较当前实际库存与当前历史库存。它比较我们专门跟踪的值。 (位置、状态等)

标签: mysql inventory-management historical-db


【解决方案1】:

您可能想要创建两个历史表,第一个快速确定自上次运行过程以来发生的变化,第二个跟踪库存变化的历史。

第一个表是您的 inventory 表的副本,因为它在您上次运行此夜间(每天、每小时等)流程时存在。 (我会添加一个日期时间字段来跟踪该进程上次运行的时间)。此表与您的真实库存表一起使用序列号和相关字段(位置、状态等)确定已插入、删除或更新的内容。

第二个表是库存更改日志(意味着 SERIAL XXX 有多个条目)。每当库存发生变化时,通过将在前一个表中找到的记录复制到此表来填充此表。添加另一个字段:带有值的操作(插入、更新、删除)。

伪代码:

填充插入和更新

INSERT INTO inventory_transaction (serial_number,lastupdated,ACTION, location, status)
SELECT inventory.serial_number, NOW()
  , IF(inventory_history.serial_number IS NULL, 'INSERT', 'UPDATE')
  , inventory.location
  , inventory.status
FROM inventory
LEFT JOIN inventory_history
  ON inventory.serial_number = inventory_history.serial_number
WHERE NOT (inventory.location  <=> inventory_history.location
           AND inventory.status <=> inventory_history.status);

删除:

INSERT INTO inventory_transaction (serial_number, lastupdated, ACTION)
SELECT inventory_history.serial_number, NOW(), 'DELETE'
FROM inventory_history
LEFT JOIN inventory
  ON inventory.serial_number = inventory_history.serial_number
WHERE inventory.serial_number IS NULL;

填充库存inventory_history 表:

TRUNCATE TABLE inventory_history;
INSERT INTO inventory_history(serial_number,lastchecked, location, status)
SELECT serial_number, NOW(), location, status
FROM inventory;

查看特定时间点的库存情况:

SELECT inventory_transaction.*
FROM (SELECT serial_number, MAX(lastupdated) as last_date
      FROM inventory_transaction
      WHERE lastupdated <= 'point in time'
      GROUP BY serial_number) AS correct_time
JOIN inventory_transaction
  ON inventory_transaction.serial_number = correct_time.serial_number
    AND inventory_transaction.lastupdated = correct_time.lastupdated
    AND inventory_transaction.ACTION <> 'DELETED'

【讨论】:

  • 与我所说的那样做相比,这样做有什么好处? IE 一张表,用于跟踪当天设备的更新状态。
  • @Tom - 我假设你的一个表只是事务表,随着时间的推移它会变大(另一个假设)。对于夜间处理,在确定发生了什么变化时,每个生长表都可能成为瓶颈。因此,请从考虑潜在瓶颈的流程开始。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
  • 2013-09-30
相关资源
最近更新 更多