Postgres 10:行在分区之间自动移动吗?

问题描述 投票:3回答:1

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

如果该字段的值发生变化,是否有办法让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';中。

当我试图这样做时(即ERROR: new row for relation "my_table_a" violates partition constraint),我收到以下错误:

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

postgresql partitioning postgresql-10
1个回答
1
投票

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)

它不处理跨越分区边界的更新。

因此你需要自己创建一个......这是你的设置:

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

这里的规则和fn():

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)

再来一次:

NEW

当然使用json传递PARTITION记录看起来很难看。这确实是丑陋的。但我没有时间研究10的新ON update to my_table where left(NEW.name,1) <> left(OLD.name,1) do instead功能,所以不知道执行此任务的优雅方式。希望我可以给出如何解决问题的通用概念,并且您将产生更好的整洁代码。

更新

它可能很好的想法将这种规则限制在qazxswpoi,以释放繁重的操纵需求

© www.soinside.com 2019 - 2024. All rights reserved.