2008-11-13 209 views
66

这不是真正关于“编程”的问题(不是特定于任何语言或数据库),而是更多的设计和架构。这也是“做X的最佳方式”类型的问题。我希望不会引起太多的“宗教”争议。库存数据库设计

在过去,我开发了一种以某种方式保留某种形式的物品清单(不相关的物品)的系统。有些使用不支持事务的语言/数据库。在这些情况下,我选择不将项目数量保存在项目记录中的字段中。相反数量是根据收到的库存总量计算的 - 总出售库存量。由于软件,这导致库存几乎没有差异。这些表格正确编制索引,性能良好。如果记录的数量开始影响性能,则存在归档过程。

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

我想知道在设计这样的系统时,是否有正确的方法达成共识。还有哪些资源可用,打印或联机,以便寻求这方面的指导。

感谢

+13

当你说“以前的程序员在这里发誓”时,你的意思是他们每次需要发誓时都会发誓吗? – MusiGenesis 2008-11-13 15:50:08

回答

47

我在当前公司看到了两种方法,并且肯定会倾向于第一种方法(基于股票交易计算总数)。

如果您只是在某个字段中存储总数量,则不知道如何到达该数字。没有事务历史记录,最终会出现问题。

我写的最后一个系统通过将每笔交易存储为正数量或负数量的记录来跟踪股票。我发现它工作得很好。

+1

+1我有同样的困境,现在我认为这是最好的选择 – INS 2010-11-10 20:03:24

+3

@尼尔 - 你可以评论这种方法的性能。它似乎是最受欢迎的方法,但是如果您有数百种产品和数千种交易,您计算累积总计的方式或时间。或者你是否只是在知道可以重新计算需要的情况下将累计总数存储在另一个地方并且安心? – 2011-07-13 20:01:10

+0

@Simon按理说,它只会比查询一个字段的性能低得多。我必须说,我从来没有用大量的产品来描述它。最好尝试一下,看看你的数据集有什么样的性能。然后决定是否值得在某处缓存数量。 – 2011-07-14 15:14:00

3

我会选择第一种方式,其中

库存量计算 合计库存接受 - 总 存货的出售

正确的方式, IMO。

编辑:我也想将任何股票损失/损害因素纳入系统,但我相信你已经涵盖了这一点。

9

这取决于,库存系统远不仅仅是计数物品。例如,出于会计目的,您可能需要根据FIFO(先进先出)模型了解库存的会计值。这不能通过简单的“收到的总库存 - 已售库存总量”公式计算出来。但他们的模型可能很容易计算出来,因为他们会随着会计价值的变化而改变。我不想深入细节,因为这不是编程问题,但如果他们发誓,也许你不能完全理解他们必须满足的所有要求。

4

重要的是要考虑现有的系统以及改变它的成本和风险。我使用存储类似于您的库存的数据库,但它包含审计周期和存储调整,就像收据一样。它似乎运作良好,但所有参与者都训练有素,而且仓库人员并不快学习新程序。我想建议添加一个跟踪表(类似于'事务'解决方案),然后将更改记录到日志文件中库存水平。更新对库存水平的大部分更改应该不会太难,因此他们也会留下交易记录。您还可以添加周期性任务以每隔几个小时左右将库存水平备份到事务处理表,以便即使您错过了事务处理,您也可以发现更改何时发生或回滚到以前的状态。

如果你想看看大型应用程序是如何看待SugarCRM,他们有库存管理模块,尽管我不确定它是如何存储数据的。

1

我可以看到有两个栏目的好处,但我没有关注有关差异的部分 - 你似乎暗示有两列(进出)不易出现差异,而不是单列(当前)。这是为什么?

7

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

  • 项目总和的数量相对较少
  • 有很少或没有特殊情况要考虑(返回,调整等)
  • 库存项目数量上没有另一方面需要经常

,如果您有大量的项目,一些特殊情况下,频繁的访问,这将是更有效地维持项目数量

还要注意,如果你的系统有差异,然后它有缺陷应追踪并消除

我已经做了系统两种方式,都可以的方式工作得很好 - 只要你不理睬错误!

3

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

如果我不能使用的交易,我会与现场计数每次我总需要时间去。如果交易是可用的,它可以安全地进行库存更新操作,并在同一事务中重新计算总,这将保证计数的准确性的储蓄(虽然我不知道这将与多个用户工作击中数据库)。

但是,如果性能不是一个真正的大问题(现代数据库足以用来计算行数,我甚至不会担心这一点),我只需坚持每次实时计数。

0

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

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 

请记住我简单地说明了这一点以及我最初的解释。我知道,只有追踪数量的库存还有很多,但在这种情况下,问题在于我们想要解决的问题。在这一点上,改变它的原因是精确地支持当前设计引起的问题的成本。

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

感谢大家为你的答案迄今。

尼尔森MARMOL

0

我们解决不同的问题,但我们对他们中的一些做法可能是有趣的你。

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

若要将此库存,你可以有3个字段:

inventory_received 
inventory_sold 
estimated_on_hand 

然后,您可以运行一个进程沿着线(每天):

SELECT * 
FROM Inventory 
WHERE estimated_on_hand != inventory_received - inventory_sold 

当然,这依赖于查看此警报的用户并对此进行处理。

此外,你可以有一个函数一些如何,无论是通过更新inventory_sold重置库存/接收,或者增加另一场“inventory_adjustment”,它可以是正的或负的。

...只是有些想法。希望它有帮助。

5

在艺术看看(协会零售技术标准)的数据模型(http://nrf-arts.org)。它使用具有记录的StockLedger表,每个项目和库存更改都在InventoryJournalEntries中进行跟踪。

1

我曾参与过解决此问题的系统。我认为理想的解决方案是一个预先计算的专栏,它可以让你两全其美。你的总数是一个领域的地方,因此没有昂贵的查找,但它不能与其他数据(数据库保持完整性)不同步。我不记得哪些RDMS支持预先计算的列,但是如果您没有交易,那也可能无法提供。

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

1

Django-inventory面向固定资产,但可能会给你一些想法。

IE:ItemTemplate中(类) - > ItemsOnHand(实例)

ItemsOnHand可以链接到更多的ItemTemplate;示例打印机&墨盒是必需的。这也允许为每个ItemOnHand设置Reorder点。

每个ItemsOnHand链接到InventoryTransactions,这允许轻松审计。 为了避免计算千日元的实际库存物品,我们使用的检查点只是一个余额+日期。要计算手头的物品查询以查找最近的检查点,并开始添加或减少物品以查找物品的当前余额。定期定义新的检查点。