mos*_*evi 4 postgresql migration partitioning default-value postgresql-11
我有下表:
CREATE TABLE orders
(
info_date date,
country_code VARCHAR,
order_total int,
CONSTRAINT orders_pk PRIMARY KEY (info_date, country_code)
) PARTITION BY LIST (country_code);
CREATE TABLE orders_def PARTITION OF orders DEFAULT;
Run Code Online (Sandbox Code Playgroud)
我插入一些行country_code
'foo'
,它们最终位于默认分区中。
一段时间后,我决定应该'foo'
有自己的分区,我该怎么做?
根据文档:
如果存在 DEFAULT 分区,并且 DEFAULT 分区中存在任何行,否则它们将适合要添加的新分区,则无法添加新分区。
这是我的尝试:
begin;
CREATE TEMP TABLE temp_table ON COMMIT DROP AS
SELECT * FROM orders where country_code = 'foo';
DELETE FROM orders where country_code = 'foo';
CREATE TABLE orders_foo PARTITION OF orders FOR VALUES IN ('foo');
INSERT INTO orders_foo select * from temp_table;
commit;
Run Code Online (Sandbox Code Playgroud)
然而这看起来像是一个黑客。
非黑客行为是首先不要陷入这种情况,当您不确定这是否是您想要的永久分区时,不使用默认分区。当我们无法正确预见未来时,有时我们不得不诉诸黑客手段。
您可以通过填充永久表,然后将其附加为新分区来稍微减少黑客攻击,而不是使用临时表来处理数据的输出和输入。
begin;
CREATE TABLE orders_foo (like orders);
INSERT into orders_foo SELECT * FROM orders where country_code = 'foo';
DELETE FROM orders where country_code = 'foo';
ALTER TABLE orders ATTACH PARTITION orders_foo FOR VALUES IN ('foo');
commit;
Run Code Online (Sandbox Code Playgroud)
您还可以将 INSERT 和 DELETE 合并到一条语句中,但我不知道这是否真的能给您带来任何有价值的东西,除了避免一次拼错“foo”的机会。
with t as (delete from orders where country_code='foo' returning *)
insert into orders_bar select * from t;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2342 次 |
最近记录: |