基础功能更改后,重新计算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列中的所有值,以使用该函数的最新版本而不锁定该表?

解决方法

在2个事件上“计算”一个生成的列。当插入行和基础列更新时。因此,您需要使用something like

更新每一行
Update customers 
   set name = name; 

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

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

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