以原子方式替换 PostgreSQL 表中所有内容的“正确”方法?

brk*_*brk 5 sql postgresql

在我最近从事的项目中,许多(PostgreSQL)数据库表只是用作大查找数组。我们有几个后台工作服务,它们定期从服务器提取最新数据,然后用最新数据替换表的所有内容。替换必须是原子的,因为我们不希望查找器看到部分完成的表。

我认为最简单的替换方法是这样的:

BEGIN;
DELETE FROM some_table;
COPY some_table FROM 'source file';
COMMIT;
Run Code Online (Sandbox Code Playgroud)

但我发现很多生产代码都使用这种方法:

BEGIN;
CREATE TABLE some_table_tmp (LIKE some_table);
COPY some_table_tmp FROM 'source file';
DROP TABLE some_table;
ALTER TABLE some_table_tmp RENAME TO some_table;
COMMIT;
Run Code Online (Sandbox Code Playgroud)

(我省略了一些逻辑,例如更改序列的所有者等)

我只是看不出这种方法有什么优点。尤其是经过一些发现和实验之后。SQL 语句类似于ALTER TABLEDROP TABLE获取ACCESS EXCLUSIVE锁,它甚至会阻塞 SELECT。

谁能解释一下后一个 SQL 模式试图解决什么问题?或者它是错误的,我们应该避免使用它?