库存系统:基于交易或存储数量,使用触发器更新?
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区分