这实际上不是一个关于“编程”的问题(不特定于任何语言或数据库),而是更多关于设计和架构的问题。这也是一个“做某事的最佳方法是什么”类型的问题。我希望不会引起太多的“宗教”争议。

过去,我开发过以某种方式保留某种形式的物品库存(与物品无关)的系统。有些使用不支持事务的语言/数据库。在这些情况下,我选择不保存项目 现有数量 在项目记录的字段中。相反, 现有数量 计算方式为收到的库存总计 - 销售的库存总计。这导致库存几乎不会因为软件而出现差异。这些表索引正确并且性能良好。有一个归档过程,以防记录量开始影响性能。

现在,几年前我开始在这家公司工作,我继承了一个跟踪库存的系统。但数量保存在一个字段中。注册条目后,收到的数量将添加到该项目的数量字段中。当商品售出时,数量会被减去。这导致了差异。在我看来,这不是正确的方法,但这里以前的程序员对此深信不疑。

我想知道设计这样的系统的正确方法是否存在共识。还有哪些资源(印刷版或在线版)可用于寻求这方面的指导。

谢谢

有帮助吗?

解决方案

我已经在我现在的公司看到了两种方法,并且肯定会倾向于第一种方法(根据股票交易计算总数)。

如果您只在某个地方存储总数量,则不知道您是如何到达该数字的。没有交易记录,您最终可能会遇到问题。

我写的最后一个系统通过将每笔交易存储为具有正数或负数的记录来跟踪库存。我发现它运作良好。

其他提示

这取决于,库存系统不仅仅是计算物品。例如,出于会计目的,您可能需要基于FIFO(先进先出)模型了解库存的会计价值。这不能通过简单的“收到的总库存量 - 销售的库存总量”来计算。式。但他们的模型可能很容易计算出来,因为他们会随着时间的推移修改会计价值我不想详细说明,因为这不是编程问题,但如果他们发誓,也许你并不完全理解他们必须满足的所有要求。

两者都有效,具体取决于具体情况。当满足以下条件时,前者是最好的:

  • 求和的项目数量相对较少
  • 很少或没有需要考虑的特殊情况(退货、调整等)
  • 库存物品数量并不经常需要

另一方面,如果您的物品数量较多,且有一些特殊情况,并且访问频繁,那么维护物品数量会更有效率

另请注意,如果您的系统存在差异,那么 它有错误 应该追踪并消除

我已经用两种方式完成了系统,并且两种方式都可以很好地工作 - 只要你不忽略错误!

查看ARTS(零售技术标准协会)数据模型( http://nrf-arts.org )。它使用StockLedger表并记录每个项目,并在InventoryJournalEntries中跟踪所有库存变化。

考虑现有系统以及更改它的成本和风险非常重要。我使用的数据库存储与您类似的库存类型,但它包括审核周期和存储调整,就像收据一样。它似乎运作良好,但参与的每个人都受过良好的训练,仓库工作人员并不是很快就能学会新的程序。

在您的情况下,如果您在不更改整个数据库结构的情况下寻找更多跟踪,那么我建议添加跟踪表(类似于“事务”解决方案),然后将更改记录到库存中水平。将大多数更改更新到库存级别应该不会太难,这样它们也会留下交易记录。您还可以每隔几个小时左右添加一个定期任务来将库存级别备份到事务表,这样即使您错过了一个事务,您也可以发现更改发生的时间或回滚到之前的状态。

如果您想查看大型应用程序的工作方式,请查看 SugarCRM ,他们有和库存管理模块虽然我不确定它是如何存储数据的。

我认为这实际上是一个一般的最佳实践问题,关于每次需要总计时执行(相对)昂贵的计数,每次更改时执行计数,然后将计数存储在字段中并随时读取该字段你需要一个总数。

如果我不能使用交易,我会在每次需要总计时使用实时计数。如果交易可用,则可以安全地执行库存更新操作并在同一交易中保存重新计算的总数,这将确保计数的准确性(尽管我不确定这对多个用户是否有效)点击数据库)。

但是如果性能不是一个真正的大问题(现代数据库在计算行数方面已经足够好了,我甚至很少担心这个问题)我每次都会坚持使用实时计数。

我会选择第一种方式,

  

计算现有数量   收到的库存总量 - 总计   库存已售出

正确的方式,IMO。

编辑:我还想将系统中的任何库存损失/损坏考虑在内,但我相信你已经涵盖了这一点。

我以前曾在解决这个问题的系统上工作过。我认为理想的解决方案是预先计算的列,它可以让您获得两全其美的效果。你的总数将是一个字段,因此没有昂贵的查找,但它不能与其余数据不同步(数据库保持完整性)。我不记得哪些RDMS支持预先计算的列,但如果您没有事务,则可能也不可用。

您可能使用触发器伪造预先计算的列(非常有效......我看不到任何缺点)。你可能需要交易。恕我直言,在进行这种受控的非规范化时保持数据完整性是触发器的唯一合法用途。

Django-inventory 更多地针对固定资产,但可能会给你一些想法。

IE:ItemTemplate(class) - > ItemsOnHand(实例)

ItemsOnHand可以链接到更多ItemTemplates;示例打印机&墨盒是需要的。这也允许为每个ItemOnHand设置重新订购点。

每个ItemsOnHand都链接到InventoryTransactions,这样可以轻松审核。 为了避免计算来自数千个投资交易的实际现有项目,使用的检查点只是余额+日期。要计算现有项目查询以查找最新检查点并开始添加或减少项目以查找项目的当前余额。定期定义新的检查点。

我可以看到拥有这两个列的一些好处,但是我没有跟踪有关差异的部分 - 你似乎暗示拥有两列(进出)不像单列那样容易出现差异(当前)。那是为什么?

没有一列或两列,我的意思是“收到的库存总量 - 销售库存总量”是这样的:

Select sum(quantity) as inventory_received from Inventory_entry
Select sum(quantity) as inventory_sold from Sales_items

然后

Qunatity_on_hand = inventory_received - inventory_sold

请记住,我过度简化了这一点以及我的初步解释。我知道还有更多的库存只是跟踪数量,但在这种情况下,问题在于我们想要解决的问题。在这一点上,改变它的原因是支持当前设计引起的问题的成本。

我还想提一下,虽然这不是“编码”。问题与算法和设计有关,恕我直言是非常重要的主题。

感谢大家到目前为止的答案。

Nelson Marmol

我们解决了不同的问题,但我们对其中一些问题的处理方法可能对您有意义。

我们允许系统进行“最佳猜测”,并向用户定期反馈任何看起来错误的猜测。

要将此应用于广告资源,您可以拥有3个字段:

inventory_received
inventory_sold
estimated_on_hand

然后,你可以按照以下方式运行一个过程(每天?)

SELECT * 
FROM   Inventory
WHERE  estimated_on_hand != inventory_received - inventory_sold

当然,这依赖于用户查看此警报并对其进行操作。

此外,您可以通过更新inventory_sold / received,或者可能添加另一个字段“inventory_adjustment”来重置库存,这可能是正面的,也可能是负面的。

......只是一些想法。希望它有用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top