postgresql版本将数据从一个表移动到另一个表

Igg*_*man 14 sql postgresql

我想将一些数据从一个表移动到另一个表(可能有不同的模式).想到的直接解决方案是 -

start a transaction with serializable isolation level;
INSERT INTO dest_table SELECT data FROM orig_table,other-tables WHERE <condition>;
DELETE FROM orig_table USING other-tables WHERE <condition>;
COMMIT;
Run Code Online (Sandbox Code Playgroud)

现在如果数据量相当大并且<condition>计算成本昂贵怎么办?在PostgreSQL中,RULE或存储过程可用于动态删除数据,仅评估条件一次.哪种解决方案更好?还有其他选择吗?

ADT*_*DTC 44

[扩展dvv的答案 ]

您可以按如下方式移动到现有表.对于不匹配的架构,您应指定列.

WITH moved_rows AS (
    DELETE FROM <original_table> a
    USING <other_table> b
    WHERE <condition>
    RETURNING a.* -- or specify columns
)
INSERT INTO <existing_table> --specify columns if necessary
SELECT [DISTINCT] * FROM moved_rows;
Run Code Online (Sandbox Code Playgroud)

但是您希望将数据移动到表(而不是现有表)中,外部语法不同:

CREATE TABLE <new_table> AS
WITH moved_rows AS (
    DELETE FROM <original_table> a
    USING <other_table> b
    WHERE <condition>
    RETURNING a.* -- or specify columns
)
SELECT [DISTINCT] * FROM moved_rows;
Run Code Online (Sandbox Code Playgroud)

  • 这个操作是原子的吗?“DELETE”和“INSERT”之间会发生什么事情吗? (2认同)

j_r*_*ker 7

如果条件太复杂,你不想执行它两次(BTW听起来不太可能,但无论如何),一种可能性是ALTER TABLE ... ADD COLUMN在原始表上添加一个布尔字段,并UPDATE在表上运行将该字段设置为true WHERE <condition>.然后你INSERTDELETE命令可以简单地检查此列的WHERE条款.

之后不要忘记从源表和目标表中删除该列!

嗯,更不干扰的是创建一个新的临时表,其唯一目的是包含您想要包含的记录的PK.首先INSERT在此表中"定义"要操作的行集,然后与此表连接以进行表复制INSERTDELETE.由于表PK被索引,因此这些连接将很快.


[编辑] 斯科特贝利在评论中的建议显然是正确的方法,希望我自己想到它!假设所有原始表的PK字段都将出现在目标表中,则不需要临时表 - 只需使用复杂WHERE条件插入目标,然后DELETE通过连接到此表从原始表中插入.现在建议一个单独的桌子我觉得很蠢!:)

  • 您不需要临时表或两次进行昂贵的计算.在插入新表时进行一次计算.然后从记录在新表中的旧表中删除. (4认同)

dvv*_*dvv 7

您可以使用Postgres 9.1中的SINGLE查询移动数据.请参阅http://www.postgresql.org/docs/9.1/static/queries-with.html "数据修改语句中的数据"部分


pce*_*ent -1

您可以将表数据转储到文件中,然后使用COPY 通常COPY比 更快地将其插入到另一个表中INSERT

  • 复制将比插入外部数据更快。OP 正在处理数据库中已有的数据,因此插入比导出然后复制回要快。 (3认同)