Mysql 必须插入记录,然后更新同一记录才能保证1:1关系设计?
假设一个Mysql 必须插入记录,然后更新同一记录才能保证1:1关系设计?,mysql,sql,database-design,database-performance,relationships,Mysql,Sql,Database Design,Database Performance,Relationships,假设一个订单有许多行项目,我们将订单的总成本(基于订单行上的价格总和)存储在orders表中 -------------- orders -------------- id ref total_cost -------------- -------------- lines -------------- id order_id price -------------- 在一个简单的应用程序中,订单和行是在签出过程的同一步骤中创建的。这意味着 INSERT INTO orders ....
订单
有许多行
项目,我们将订单的总成本(基于订单行上的价格总和)存储在orders表中
--------------
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
我遇到的问题是试图找出存储订单总成本的最佳方法。我不想非得这么做
您的想法是什么?我认为最好不要使用订单总计列或表格
只要在需要显示行记录时,通过求和来计算订单总数。想象一下,如果行记录发生变化,那么您必须不断维护另一列或表,以更新订单的总价 我认为最好不要有order total列或表
只要在需要显示行记录时,通过求和来计算订单总数。想象一下,如果行记录发生变化,那么您必须不断维护另一列或表,以更新订单的总价 不需要该表,因为它可以存储为orders表的一列
--------------
orders
--------------
id
ref
total_cost
--------------
--------------
lines
--------------
id
order_id
price
--------------
是否值得将其存储为新列取决于读取值的次数与所做的更改(以及计算成本)
如果它读了很多,但没有经常更改,并且需要花费不可接受的时间来计算,那么维护一个新的总计列是值得的。否则,您最好每次都计算它,可能是通过一个视图,这样您就不必在其所选位置的计算中编写代码。该表不需要,因为它可以存储为orders表的一列
--------------
orders
--------------
id
ref
total_cost
--------------
--------------
lines
--------------
id
order_id
price
--------------
是否值得将其存储为新列取决于读取值的次数与所做的更改(以及计算成本)
如果它读了很多,但没有经常更改,并且需要花费不可接受的时间来计算,那么维护一个新的总计列是值得的。否则,您最好每次都计算它,可能是通过一个视图,这样您就不必在其所选的任何位置都在计算中编码。我同意其他评论者的观点,除非计算行项目的总成本非常昂贵,否则您最好是通过SUM/GROUP-BY-query动态计算
但如果您仍然想进行前期总成本计算,只需在开始运行SQL插入之前在内存中进行计算即可。毕竟,您有数据要插入到行项目中,所以只需对它们进行迭代,并首先对总成本求和,然后使用总成本创建订单记录。在插入行项目时遵循这一点。我同意其他评论者的看法,即除非计算行项目的总成本非常昂贵,否则最好是通过查询进行汇总/分组
但如果您仍然想进行前期总成本计算,只需在开始运行SQL插入之前在内存中进行计算即可。毕竟,您有数据要插入到行项目中,所以只需对它们进行迭代,并首先对总成本求和,然后使用总成本创建订单记录。然后插入行项目。正如其他人所建议的那样,最好是动态计算总和 我只想补充一点,因此如果您正确选择
行
上的主键,相同顺序的行将存储在一起物理上接近,您将能够以最小的I/O计算整个订单的总和(即非常快)
为此,放弃
行
中的代理PK,并使用自然PK:{order\u id,line\u no}
正如其他人所建议的,可能最好是动态计算总和
我只想补充一点,因此如果您正确选择行
上的主键,相同顺序的行将存储在一起物理上接近,您将能够以最小的I/O计算整个订单的总和(即非常快)
为此,放弃
行中的代理PK,使用自然PK:{order\u id,line\u no}
我将回应其他答案,并说,除非这样做的成本太高,否则我会在需要时从行
表中计算总成本
或者,可以定义更新订单的触发器。总成本。但是,需要在行上的插入
、更新
和删除
之后定义触发器:
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;
我将重复其他答案,并说,除非这样做的成本高得令人无法接受,否则我会在需要时从行
表中计算总成本
或者,可以定义更新订单的触发器。总成本。但是,需要在行上的插入
、更新
和删除
之后定义触发器:
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;
当然,如果存储聚合数据,则必须具有触发器以确保其始终保持正确。