Postgresql
使用預設分區中已存在的值創建新表分區
我有下表:
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;
我插入了一些行,
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;
但它似乎是一個黑客。
非黑客將首先不進入這種情況,當您不確定這是否是您想要的永久分區時不使用預設分區。當我們無法正確預見未來時,有時我們不得不求助於黑客。
您可以通過填充一個永久表,然後將其作為新分區附加,而不是使用臨時表來處理數據的出入,從而稍微減少黑客攻擊。
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;
您也可以將 INSERT 和 DELETE 組合到一個語句中,但我不知道這真的會給您帶來任何有價值的東西,除了避免一次拼錯“foo”的機會。
with t as (delete from orders where country_code='foo' returning *) insert into orders_bar select * from t;