长时间汇总分类帐。 (对帐,快照,总和?)

时间:2018-07-09 23:11:41

标签: mysql sql database laravel eloquent

我们正在构建一个仓库库存管理系统,并具有一个库存移动表,该表记录每种产品及其所存储的每个位置进出系统的库存。即

  • 将10单位产品A接收到位置A
  • 将10单位产品A移到位置B,然后从位置A移出。
  • 从位置B中删除(出售)了1个单位

...等等。

这意味着要弄清楚我们将在每个位置存储每种产品的数量;

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

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

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

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

是否已经有定义好的最佳实践方式来处理这种事情?很想听听您的想法!

1 个答案:

答案 0 :(得分:1)

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

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

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

祝你好运!