5

我正在实施一种请求机制,用户必须批准请求。为此,我实现了一个临时表和主表。最初,当请求被添加时,数据将被插入到临时表中,经批准后将被复制到主表中。

问题是批准后将有超过 5k 行移动到主表 + 明细表中的每行另外 3-5 行(存储详细信息)。我目前的实现是这样的

//Get the rows from temporary table (batch_temp)
    //Loop through the data
        //Insert the data to the main table (batch_main) and return the id 
        //Get the details row from the temporary detail table (batch_temp_detail) using detail_tempid
            //Loop through the data
                //Insert the details to the detail table (batch_main_detail) with the main table id amount_id
            //End Loop  
    //End Loop

但是这个实现至少需要 20k 查询。有没有更好的方法来实现相同的。

我试图创建一个 sqlfiddle 但无法创建一个。所以我将查询粘贴到pgsql.privatepaste.com

4

3 回答 3

2

对不起,我不熟悉 PostgreSQL。我的解决方案是在 MySQL 中,我希望它能有所帮助,因为如果它们(MySQL 和 PostgreSQL)是相同的。

首先,我们应该在您的batch_main表中再添加 1 个字段来跟踪每个batch_main记录的原始batch_temp记录。

ALTER TABLE `batch_main`
    ADD COLUMN tempid bigint;

然后,在批准后,我们​​将通过 1 个查询插入 5k 行:

INSERT INTO batch_main
    (batchid, userid, amount, tempid)
    SELECT batchid, userid, amount, amount_id FROM batch_temp;

因此,对于每个新的 batch_main 记录,我们都有其原始batch_temp记录的 id。然后,插入详细记录

INSERT INTO `batch_main_detail`
    (detail_amount, detail_mainid)
    SELECT
        btd.detail_amount, bm.amount_id
        FROM 
            batch_temp_detail `btd`
            INNER JOIN batch_main `bm` ON btd.detail_tempid = bm.tempid

完毕!

P/S:我对您命名字段的方式有点困惑,并且由于我不了解 PostgreSQL,并且通过查看您的语法,您可以对表batch_tempbatch_main的主键使用相同的序列吗?如果可以,则无需再添加 1 个字段。

希望这有帮助,

于 2013-05-29T10:58:00.010 回答
0

只需更新您的架构。您应该拥有主表中的所有数据,而不是拥有两个表:一张main和一张temporary,但有一个标志,指示某条记录是否被批准。最初它将被设置为 false,一旦获得批准,它将被简单地设置为 true,然后数据可以显示在您的网站等上。这样您就不需要write两次数据,甚至不必从一个表中移动它给另一个

于 2013-05-29T06:29:45.353 回答
0

您还没有指定您正在使用的 RDBMS,但是带有 SELECT 的旧​​ INSERT 必须在一个命令中完成:

insert main (field1,...,fieldN) select field1,...,fieldN from temporary
于 2013-05-29T08:21:56.027 回答