必须插入记录,然后更新相同的记录保证1:1的关系设计?

时间:2012-06-28 20:58:35

标签: mysql sql database-design database-performance relationships

假设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. 根据行计算订单成本,然后更新在订单表中创建的记录
  4. 这对于初学者的订单来说意味着一个可以为空的total_cost字段...

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

    你有什么想法?

5 个答案:

答案 0 :(得分:3)

我认为没有订单总计列或表更好。

只需在需要显示行记录时对行记录求和,即可计算订单总数。想象一下,如果行记录发生变化,那么您将不得不经常维护另一列或表来更新订单的总价。

答案 1 :(得分:3)

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

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

如果它读了很多但没有经常更改,并且需要花费不可接受的时间来计算它,那么值得保留一个新的总列。否则你最好每次计算它,也许通过一个视图,所以你不必在计算的任何地方编码。

答案 2 :(得分:2)

我同意其他评论者的意见,除非计算整个项目的总成本在资源方面非常昂贵,否则最好通过SUM / GROUP BY查询动态执行此操作。

但是如果你仍然想要进行前期总成本计算,那么在开始运行SQL插入之前,只需在内存中计算它。毕竟,您要将数据插入到行项目中,因此只需迭代它们并首先总计总成本,然后使用总成本创建订单记录。关注订单项插入。

答案 3 :(得分:2)

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

我只想添加InnoDB clusters its tables,所以如果您正确选择lines上的PK,相同订单的行将物理关闭存储在一起并且您将能够以最小的I / O(即非常快速)计算整个订单的总和。

为此,请放弃lines中的代理PK并使用自然PK:{order_id, line_no}

答案 4 :(得分:2)

我会回答其他答案并说,除非这样做的费用高得令人无法接受,否则我会根据需要从lines表中计算总费用。

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

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;