1

假设一个Order有许多Line项目,我们将订单的总成本(基于订单行上的价格总和)存储在订单表中。

--------------
orders
--------------
id
ref
total_cost
--------------

--------------
lines
--------------
id
order_id
price
--------------

在一个简单的应用程序中,订单和行是在结帐过程的同一步骤中创建的。所以这意味着

INSERT INTO orders .... 

-- Get ID of inserted order record
INSERT into lines VALUES(null, order_id, ...), ...

我们在创建订单记录后获取订单 ID。

我遇到的问题是试图找出存储订单总成本的最佳方式。我不想

  1. 创建订单
  2. 在订单上创建行
  3. 根据行计算订单成本,然后更新在 1. 在订单表中创建的记录

这意味着初学者的订单上有一个可为空的 total_cost 字段......

到目前为止,我的解决方案是创建一个与orders表 1:1 关系的order_totals表。但我认为这是多余的。理想情况下,由于计算总成本(订单行)所需的所有内容都在数据库中,所以每次需要时我都会计算出该值,但这非常昂贵。

你怎么认为?

4

5 回答 5

3

我认为最好不要有订单总计列或表格。

只要您需要显示它们,只需通过对 Line 记录求和来计算订单总额。想象一下,如果行记录发生变化,那么您将不得不不断维护另一个列或表来更新订单的总价格。

于 2012-06-28T21:02:29.110 回答
3

该表不是必需的,因为它可以存储为订单表的列。

是否值得将其存储为新列取决于您将读取值与所做更改的次数(以及计算成本)。

如果它被阅读了很多但没有经常更改,并且需要花费不可接受的时间来计算,那么维护一个新的总列是值得的。否则你最好每次都计算它,也许是通过一个视图,这样你就不必在它选择的任何地方都在计算中编码。

于 2012-06-28T21:05:54.730 回答
2

我同意其他评论者的观点,除非计算订单项的总成本在资源方面异常昂贵,否则您最好使用 SUM/GROUP BY 查询即时执行此操作。

但是,如果您仍想进行前期总成本计算,只需在开始运行 SQL 插入之前在内存中计算它。毕竟,您有数据要插入到行项目中,所以只需对其进行迭代并先总结总成本,然后创建带有总成本的订单记录。紧随其后的是订单项插入。

于 2012-06-28T21:15:38.917 回答
2

正如其他人所建议的那样,动态计算总和可能更好。

我只想补充一点,InnoDB 将其表集群化,因此如果您lines正确选择 PK,相同订单的行将物理上靠近存储在一起,您将能够以最小的 I 计算整个订单的总和/O(即非常迅速)。

为此,请放弃替代 PKlines并使用自然 PK: {order_id, line_no}

于 2012-06-28T21:32:25.787 回答
2

我会回应其他答案并说,除非这样做的成本高得无法接受,否则我会在需要lines时从表格中计算总成本。

或者,可以定义orders.total_cost适当更新的触发器。INSERT但是,需要在UPDATEDELETEon之后定义触发器lines

CREATE TRIGGER after_insert_lines AFTER INSERT ON lines FOR EACH ROW
  UPDATE orders SET total_cost = total_cost + NEW.price;

CREATE TRIGGER after_update_lines AFTER UPDATE ON lines FOR EACH ROW
  UPDATE orders SET total_cost = total_cost - OLD.price + NEW.price;

CREATE TRIGGER after_delete_lines AFTER DELETE ON lines FOR EACH ROW
  UPDATE orders SET total_cost = total_cost - OLD.price;
于 2012-06-28T21:33:47.200 回答