将客户订单保存到数据库并确保该订单的完整性得以保留

时间:2014-07-09 10:15:43

标签: ruby-on-rails database design-patterns model integrity

在我的Rails应用程序中,我需要存储客户订单,以便店主仍然可以在以后查看订单。

我担心订单最终确定后,商店员工可能需要更改价格或细节或产品。

假设产品仅通过product_id链接到订单,这将损害最终订单的完整性。

管理此问题的常用方法有哪些?

我能想到的一个选择是在幕后不允许更新产品。如果工作人员执行"更新",在幕后,旧记录只会被标记为" old"并在其中创建了一个新产品。

另一种选择可能是在交易发生之日出现的产品的订单模型中存储哈希值。

这有什么优点和缺点?还有其他可能性我应该考虑作为设计公认的模式来处理这个问题吗?

1 个答案:

答案 0 :(得分:1)

两种最常见的方法是

  • 存储订单下达时的所有值,
  • 存储值的更改历史记录,因此可以根据订单日期重新创建它们。

因此,如果您存储所有值,订单的订单项表可能如下所示。 (订单日期不在此表中。)您可能还需要存储计算值,如延长价格(数量*单位价格),销售税等。

order_num  quantity  units  product_code   product_name  unit_price
--
10132      5         each   13376-A        Widgets       $ 1.99
10132      2         dozen  BR549          Fimbels       $24.99
10132      3         boxes  THRUM          Thrums        $ 8.99

如果存储计算值,请使用验证以确保它们与基值保持同步。

如果您要存储历史记录,则产品表可能如下所示。 (价格改变一次;名称改变一次。)

product_code  product_name  unit_price  units  from_date    to_date
--
13376-A       Widgets       $1.99       each   2014-01-01   (NULL or END_OF_TIME)
13376-A       Widgets       $1.95       each   2012-02-13   2014-12-31
13376-A       Wid-gets      $1.95       each   2009-06-17   2012-02-12
...

订单项表格会存储产品代码。日期将在订单表中。基于line_items.product_code和orders.order_date的连接将从该历史记录表中获取正确的详细信息。 END_OF_TIME是dbms支持的最大日期值。

在任何一种情况下,您都需要仔细考虑何时以及如何允许更新表。 (因为,当您今天打印订单10132时,它必须与下订单时打印的订单相同。)

在许多情况下,系统允许对订单项进行 no 更改。相反,他们使用补偿订单项。如果有人订购了5打,并且他们打算订购6打,那么系统将不允许你将5改为6.相反,它只会添加另外10个fimbels的订单项。 (或者出现让你将5改为6,而是存储一个补偿的行项目。)