库存系统:基于交易或存储数量,使用触发器更新?

Posted

技术标签:

【中文标题】库存系统:基于交易或存储数量,使用触发器更新?【英文标题】:inventory system: transaction-based or store quantity, update with trigger? 【发布时间】:2011-07-17 10:58:05 【问题描述】:

您将如何为 RDBMS 中的库存管理系统设计数据模型?

你愿意:

    存储每次购买和使用情况,并使用 SUM() 和 GROUP BY 即时计算仓库数量? 同1,但每天合并数量,使用前一天的值? 数量作为 Int 字段,通过应用层更新? 同3,但使用DB触发器?

基于交易的库存系统在捕获的详细信息水平方面似乎更胜一筹,但它更难正确实施。性能会随着时间的推移而下降。

基于数量的库存系统似乎更容易,但可能需要额外的锁定以确保数量值是 ++ 或 -- 正确。

你会选择哪一个?

【问题讨论】:

【参考方案1】:

如果审计跟踪很重要,您需要交易数据。而且,我从未见过真正的系统不是这样的。

就性能而言,我会:

    定期捕获非规范化值 - 例如每小时或每天 将此非规范化过程中涉及的事务记录移动到另一个表(即从“当前”到“仓库”)。

那么总计将是这个非规范化值和当前交易的总和。

这种方法还有助于备份,因为事务记录的数量可能会超过可用磁盘空间。因此,例如将仓库写入磁带备份。

【讨论】:

太棒了,我认为这是更好但确实更复杂的解决方案,因为在 ORM 中进行“非规范化”并不容易。而且我需要使用 cfscheduler 来安排任务... 为此我会依赖数据库任务调度程序。至于总和,假设您有一个名为Account 的类,其方法为getWarehouseTotal()getTransactions()getTotal()。最后一种方法getTotal() 可以是一个仅在循环中添加getWarehouseTotal()getTransactions() 总和的CF 代码。不是最优雅或最高效的,但使用 ORM 进行持久化很容易实现。【参考方案2】:

我很可能会走触发路线,并在事务被推送到数据库时更新数量。这使得无需一堆子查询和计算就可以很容易地查看当前数量。

如果在触发器中完成,那么您可以确保无论交易来自何处,您的库存表中的数量都将始终更新(无论是通过硬插入还是通过应用程序添加的交易)。

如果存在日志记录问题,则将一些日志记录包装到您的触发器中,以便在单独的日志记录表中跟踪之前/之后的数量。

触发器可能如下所示(未经测试):

CREATE TRIGGER [dbo].[OrderAdded] 
   ON  [dbo].[Orders] 
   AFTER INSERT
AS 
BEGIN
    DELCARE @ProductID int; DECLARE @Qty int;
    SET @ProductID = (SELECT ProductID FROM inserted);
    SET @Qty = (SELECT Qty FROM inserted);
    UPDATE StockTable 
    SET Stock = Stock - @Qty
    WHERE ID = @ProductID

END

只要您为 ID 和 Stock 字段正确索引了您的 StockTable,我认为不会有性能问题需要担心(鉴于此,我当然会编造所有这些您没有提供任何数据库信息)。

【讨论】:

你能告诉我,你的触发器是什么样子的?谢谢 您将如何解决性能随时间下降的问题?谢谢 在我的回答中添加了一个触发器示例。 谢谢 Dan,但与在事务中的应用层中执行 -- 相比,触发器有什么好处? 哪个应用程序?如果您有多个系统连接到订单怎么办?如果您在应用程序之外添加订单(无论出于何种原因),那么您将失去那一点库存跟踪。

以上是关于库存系统:基于交易或存储数量,使用触发器更新?的主要内容,如果未能解决你的问题,请参考以下文章

使用触发器插入后更新另一个表?

MySQL触发器 trigger之after与before区分

架构设计 | 基于电商交易流程,图解TCC事务分段提交

两张表 在一张表中插入数据时要使用触发器也更新另一张 有错误

插入后使用触发器更新多行(sql server)

MySQL 查询 - 创建一个触发器,在销售发生后更新库存水平