【问题标题】:Summing a ledger over long period of time. (reconciliation, snapshots, rolling sum?)在很长一段时间内汇总分类帐。 (和解、快照、滚动总和?)
【发布时间】:2018-12-17 16:57:01
【问题描述】:

我们正在构建一个仓库库存管理系统,并有一个库存移动表,用于记录每个产品和每个存储位置的库存进出系统。即

  • 10 件产品 A 被接收到位置 A
  • 10 件产品 A 被移至位置 B 并从位置 A 移除。
  • 从位置 B 移除(出售)1 个单位

...等等。

这意味着我们要计算出每种产品在每个位置的存储量;

"SELECT SUM('qty') FROM stock_movements GROUP BY location, product"

(我们实际上使用 Eloquent,但我以 SQL 为例)

随着时间的推移,这意味着我们的库存变动表将增长到数百万行,我想知道如何最好地管理它。我能想到的选项:

  • 总结上面分组的行并接受它可能会随着时间的推移而变慢。我不确定在实际开始导致任何性能问题之前需要多少行。当通过我们的 API 请求完整的库存日志时,必须对每件产品的每一行求和,因此这将编译成一个相当大的计算。
  • 在 cron 上每天/每周/每月等创建汇总行的快照,然后即时添加最新行的总和。
  • 创建一个单独的表格,其中包含随每个库存变动而增加和减少的实时库存水平。库存变动表显示所有变动的完整历史,而新表仅显示实时金额。我们将在这里使用数据库事务来确保它们保持同步。

是否已经有明确的最佳实践方式来处理此类事情?很想听听你的想法!

【问题讨论】:

    标签: mysql sql database laravel eloquent


    【解决方案1】:

    好消息是,您的系统已经是很多人认为数据库世界应该发展的地方:事件溯源。 ES 只是针对一个对象存储每个事件,在这种情况下是您的位置,为了获得当前状态,您必须从一个空对象开始并重播所有对象事件。

    当然,这可能很耗时,最后两个要点是处理它的标准方法。首先,您可以使用该位置的当前当前总计创建常规快照,然后当有人询问当前当前总计时,您只需要重播自上次快照以来的事件。其次,您可以有一个单独的当前值表,并且每当您将记录插入事件存储时,您也会更新当前值。如果它们不同步,您总是可以重新开始并重新播放整个事件系列。

    这两种情况通常通过中间队列服务进行管理,例如 SQL 的 Service Broker、RabbitMQ 或 Amazon 的 SQS:您无需将事件直接插入事件存储,而是将更改发送到队列和处理代码队列将更新您的快照。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-13
      • 2016-12-19
      • 2011-12-05
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 2021-04-24
      相关资源
      最近更新 更多