问题描述
为具有生成的列的表成像,如下所示:
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)级别。
但是,如果在此过程中继续允许更新,则需要查找死锁。