首页 > 解决方案 > 基础函数更改后重新计算 Postgres 生成的列中的值

问题描述

使用生成的列对表进行映像,如下所示:

CREATE OR REPLACE FUNCTION extract_first_name(p_name text) RETURNS text
LANGUAGE SQL IMMUTABLE
AS $$
    SELECT split_part(p_name, ' ', 1);
$$;

CREATE TABLE customers (
    id serial,
    name text,
    first_name text GENERATED ALWAYS AS (extract_first_name(name)) STORED
);

后来有人发现这个extract_first_name功能太简单了,需要改一下。然后更新它,但first_name列中的值保持不变。我们如何以最简单和最有效的方式重新计算first_name列中的所有值以使用最新版本的函数而不锁定表?

标签: sqlpostgresqlsql-functiongenerated-columns

解决方案


生成的列在 2 个事件上“计算”。插入行和更新基础列的时间。因此,您需要使用类似的内容更新每一行

Update customers 
   set name = name; 

这将根据需要更新表中的每一行。但是由于 Postgres 使用MVCC模型,这不会阻止其他人在操作期间进行选择。

使用 MVCC 并发控制模型而不是锁定的主要优点是,在 MVCC 中,为查询(读取)数据而获得的锁与为写入数据而获得的锁不会冲突,因此读取永远不会阻塞写入,写入永远不会阻塞读取。即使通过使用创新的可序列化快照隔离 (SSI) 级别提供最严格的事务隔离级别,PostgreSQL 也保持此保证。

但是,如果在此过程中继续允许更新,则需要注意死锁。


推荐阅读