【发布时间】:2022-05-03 02:13:29
【问题描述】:
在 PostgreSQL 13 上,我有一个这样定义的表:
create table my_table (
id serial8 primary key,
title varchar(50),
description varchar(512),
french_vector_text tsvector generated always as (to_tsvector('french', coalesce(title, '') || ' ' || coalesce(description, ''))) stored
);
create index IDX_FULL_TEXT on my_table using GIN(french_vector_text);
它工作正常。但是,当我尝试更改用于生成向量的列时,像这样
alter table my_table
alter column title type varchar(100);
我收到一条错误消息,告诉我无法更改用于计算另一列的列,这是公平的。我通过删除带有索引的向量列,更改标题列,然后重新创建列和索引来使其工作。
alter table my_table
drop column french_vector_text;
alter table my_table
alter column title
type varchar(100);
alter table my_table
add column french_vector_text tsvector generated always as (to_tsvector('french', coalesce(title, '') || ' ' || coalesce(description, ''))) stored;
create index IDX_FULL_TEXT on my_table using GIN(french_vector_text);
再次运行良好,但实际上,该列是 7 列的聚合,其中一些具有相当大的文本,并且该表可能包含几万条记录。所以操作需要一些时间才能完成。
即使更改架构不是日常操作,我想知道是否有更有效的解决方案不需要删除列并完全重新创建索引。
我想过一个触发器,但我宁愿保留生成的列。所以我尝试创建一个IMMUTABLE 函数:
create function my_french_vector(text_to_transform varchar) returns tsvector as $$
BEGIN
return to_tsvector('french', text_to_transform);
end
$$ LANGUAGE plpgsql
immutable;
并使用它来代替普通的to_tsvector。但显然,它也不起作用,因为该列仍然被引用。
至于我的问题,有没有办法改变生成值中使用的列,而不必删除它并在之后重新创建整个内容?
【问题讨论】:
标签: postgresql