Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 必须插入记录,然后更新同一记录才能保证1:1关系设计?_Mysql_Sql_Database Design_Database Performance_Relationships - Fatal编程技术网

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

我遇到的问题是试图找出存储订单总成本的最佳方法。我不想非得这么做

  • 创建订单
  • 在订单上创建行
  • 根据行计算订单成本,然后更新在1中创建的记录。订单表
  • 这意味着在初学者订单上有一个可空的total_cost字段

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


    您的想法是什么?

    我认为最好不要使用订单总计列或表格


    只要在需要显示行记录时,通过求和来计算订单总数。想象一下,如果行记录发生变化,那么您必须不断维护另一列或表,以更新订单的总价

    我认为最好不要有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;
    

    当然,如果存储聚合数据,则必须具有触发器以确保其始终保持正确。