gpt4 book ai didi

postgresql - Postgres 10 : do rows automatically move between partitions?

转载 作者:行者123 更新时间:2023-11-29 11:49:13 25 4
gpt4 key购买 nike

假设我有一个父表,其中的子分区是根据字段的值创建的。

如果该字段的值发生变化,是否有办法让 Postgres 自动将行移动到适当的分区中?

例如:

create table my_table(name text)
partition by list (left(name, 1));

create table my_table_a
partition of my_table
for values in ('a');

create table my_table_b
partition of my_table
for values in ('b');

在这种情况下,如果我将 name 的值从 aaa 更改为 bbb,我如何才能自动获取它将该行移动到 my_table_b

当我尝试这样做时(即 update my_table set name = 'bbb' where name = 'aaa';),我收到以下错误:

错误:关系“my_table_a”的新行违反分区约束

最佳答案

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=f0e44751d7175fa3394da2c8f85e3ceb3cdbfe63

it doesn't handle updates that cross partition boundaries.

因此您需要自己创建一个...这是您的集合:

t=# insert into my_table select 'abc';
INSERT 0 1
t=# insert into my_table select 'bcd';
INSERT 0 1
t=# select tableoid::regclass,* from my_table;
tableoid | name
------------+------
my_table_a | abc
my_table_b | bcd
(2 rows)

规则和 fn():

t=# create or replace function puf(_j json,_o text) returns void as $$
begin
raise info '%',': '||left(_j->>'name',1);
execute format('insert into %I select * from json_populate_record(null::my_table, %L)','my_table_'||left(_j->>'name',1), _j);
execute format('delete from %I where name = %L','my_table_'||left(_o,1), _o);
end;
$$language plpgsql;
CREATE FUNCTION
t=# create rule psr AS ON update to my_table do instead select puf(row_to_json(n),OLD.name) from (select NEW.*) n;
CREATE RULE

这里是更新:

t=# update my_table set name = 'bbb' where name = 'abc';
INFO: : b
puf
-----

(1 row)

UPDATE 0

检查结果:

t=# select tableoid::regclass,* from my_table;
tableoid | name
------------+------
my_table_b | bcd
my_table_b | bbb
(2 rows)

再一次:

t=# update my_table set name = 'a1' where name = 'bcd';
INFO: : a
puf
-----

(1 row)

UPDATE 0
t=# select tableoid::regclass,* from my_table;
tableoid | name
------------+------
my_table_a | a1
my_table_b | bbb
(2 rows)

当然是用json传NEW记录看起来很难看。它确实很丑陋。但是没时间研究新的PARTITION 10 的功能,所以不知道完成此任务的优雅方式。希望我能给出您如何解决问题的一般思路,您将生成更简洁的代码。

更新

将此类规则限制为 ON update to my_table where left(NEW.name,1) <> left(OLD.name,1) do instead 可能是个好主意, 释放繁重的操作需求

关于postgresql - Postgres 10 : do rows automatically move between partitions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48028633/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com