sql - 基础函数更改后重新计算 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 个事件上“计算”。插入行和更新基础列的时间。因此,您需要使用类似的内容更新每一行
Update customers
set name = name;
这将根据需要更新表中的每一行。但是由于 Postgres 使用MVCC模型,这不会阻止其他人在操作期间进行选择。
使用 MVCC 并发控制模型而不是锁定的主要优点是,在 MVCC 中,为查询(读取)数据而获得的锁与为写入数据而获得的锁不会冲突,因此读取永远不会阻塞写入,写入永远不会阻塞读取。即使通过使用创新的可序列化快照隔离 (SSI) 级别提供最严格的事务隔离级别,PostgreSQL 也保持此保证。
但是,如果在此过程中继续允许更新,则需要注意死锁。
推荐阅读
- java - 如何将 IntStream 映射到 Runnables 列表?
- gradle - 如何在 Gradle 7 的自定义任务中使用 @Delegate?
- python - 如何从 python 中的字符串中只删除最后一个括号?
- python - 在 Plotly 中更新下拉菜单后保持数据颜色
- mysql - 如何根据 MySQL 中的值范围获取表中的特定值?
- google-cloud-platform - 使用 Ops Agent 监控 Google Cloud 中的 Apache2
- c# - C#两个同类重载之间的双向字典歧义
- reactjs - 如何测试包含子组件并使用上下文的样式化组件?
- android - 从 Android 中的外部扫描仪获取条码值
- go - Go FAQ对方法集的解释