Postgres 8.1 で列の自然な順序を変更することは可能ですか?
列の順序に依存するべきではないことを知っています-それは私がやっていることに不可欠ではありません-フィールドの順序がすべてのpgadmin からバックエンドを経由してフロントエンドに至る方法。
Postgres 8.1 で列の自然な順序を変更することは可能ですか?
列の順序に依存するべきではないことを知っています-それは私がやっていることに不可欠ではありません-フィールドの順序がすべてのpgadmin からバックエンドを経由してフロントエンドに至る方法。
実際には、列の順序をそのまま変更することもできますが、お勧めすることはほとんどありません。変更する場合は、十分に注意する必要があります。
例えば。
#CREATE TABLEテスト(a int、b int、c int); #INSERT INTO test VALUES(1,2,3); #SELECT*FROMテスト; a | b | c --- + --- + --- 1 | 2 | 3 (1行)
ここで注意が必要なのは、postgresユーザーを使用してデータベースに接続し、システムテーブルを変更できるようにする必要があることです。
#SELECT relname、relfilenode FROM pg_class WHERE relname ='test'; relname | relfilenode --------- + ------------- test_t | 27666 (1行) #SELECT attrelid、attname、attnum FROM pg_attribute WHERE attrelid = 27666; attrelid | attname | attnum ---------- + ---------- + -------- 27666 | tableoid | -7 27666 | cmax | -6 27666 | xmax | -5 27666 | cmin | -4 27666 | xmin | -3 27666 | ctid | -1 27666 | b | 1 27666 | a | 2 27666 | c | 3 (9行)
attnumは一意の列であるため、列番号を次のように変更する場合は、一時的な値を使用する必要があります。
#UPDATE pg_attribute SET attnum = 4 WHERE attname ='a' AND attrelid = 27666; 更新1 #UPDATE pg_attribute SET attnum = 1 WHERE attname ='b' AND attrelid = 27666; 更新1 #UPDATE pg_attribute SET attnum = 2 WHERE attname ='a' AND attrelid = 27666; 更新1 #SELECT*FROMテスト; b | a | c --- + --- + --- 1 | 2 | 3 (1行)
繰り返しになりますが、これはデータベースシステムテーブルで遊んでいるため、本当にこれを行う必要があると思われる場合は、細心の注意を払ってください。
これはpostgres8.3の時点で機能しており、以前のバージョンでは、マイレージが異なる場合があります。
データベースがそれほど大きくなく、ダウンタイムを許容できる場合は、次のことができます。
pg_dump --create --column-inserts databasename > databasename.pgdump.sql
CREATE TABLE
databasename.pgdump.sql の適切なステートメントを編集しsplit
コマンドを使用して分割し、編集してから、cat
drop database databasename
psql --single-transaction -f databasename.pgdump.sql
--single-transaction
とかなり遅くなるいわゆる大きなオブジェクトを使用する場合は、それらがダンプに含まれていることを確認してください。それらがデフォルトで 8.1 にあるかどうかはわかりません。
私は 2007 年に pgsql-admin でその質問をしました。Tom Lane 自身は、カタログの順序を変更することは事実上不可能であると宣言しました。
明確化: これは、現在のツールを使用しているユーザーに適用されます。というわけではありませんが、実装できませんでした。IMO、そうあるべきです。
Postgres 12 にも当てはまります。
postgres を使用して列の順序をインプレースで変更することはできません。ただし、ビューで問題を解決できます。レポート クエリの目的上、これはテーブルのように見えます。何かのようなもの:
create view my_view as select * from my_table order by some_col;
データをそのままにしておく必要がある場合は、調整する必要があります
ビューを使用して、次のように列を並べ替えた新しいテーブルを作成できます。
-- foo is the table you want to re-order columns in
drop table foo;
CREATE TABLE foo ( moo integer, bar character varying(10), baz date );
insert into foo (moo, bar, baz) values (34, 'yadz', now());
insert into foo (moo, bar, baz) values (12, 'blerp', now());
select * from foo;
┌─────┬───────┬────────────┐
│ moo │ bar │ baz │
├─────┼───────┼────────────┤
│ 34 │ yadz │ 2021-04-07 │
│ 12 │ blerp │ 2021-04-07 │
└─────┴───────┴────────────┘
-- Define your reordered columns here, don't forget one,
-- or it'll be missing from the replacement.
drop view if exists my_view;
create view my_view as ( select moo, baz, bar from foo );
select * from my_view;
DROP TABLE IF EXISTS foo2;
--foo2 is your replacement table that has columns ordered correctly
create table foo2 as select * from my_view;
select * from foo2;
--finally drop the view and the original table and rename
DROP VIEW my_view;
DROP TABLE foo;
ALTER TABLE foo2 RENAME TO foo;
select * from foo;
┌─────┬────────────┬───────┐
│ moo │ baz │ bar │
├─────┼────────────┼───────┤
│ 34 │ 2021-04-07 │ yadz │
│ 12 │ 2021-04-07 │ blerp │
└─────┴────────────┴───────┘
新しいテーブルを作成し、表示する順序で古いテーブルの列を選択することで、必要な列の順序を取得できます。
CREATE TABLE test_new AS SELECT b, c, a FROM test;
SELECT * from test_new;
b | c | a
---+---+---
2 | 3 | 1
(1 row)
これは、修飾子、制約、インデックスなどではなく、データのみをコピーすることに注意してください。
新しいテーブルが希望どおりに変更されたら、元のテーブルを削除して、新しいテーブルの名前を変更します。
BEGIN;
DROP TABLE test;
ALTER TABLE test_new RENAME TO test;
COMMIT;
残念ながら、そうではありません。列の順序は完全に Postgres 次第です。
クエリで列の順序を指定することは、唯一の信頼できる (そして健全な) 方法です。とはいえ、通常は、次の例に示すようにテーブルを変更することで、別の順序を取得できます。これは、通常、テーブルに追加された順序で列が返される (保証されていない) ためです。
postgres=# create table a(a int, b int, c int);
CREATE TABLE
postgres=# insert into a values (1,2,3);
INSERT 0 1
postgres=# select * from a;
a | b | c
---+---+---
1 | 2 | 3
(1 row)
postgres=# alter table a add column a2 int;
ALTER TABLE
postgres=# select * from a;
a | b | c | a2
---+---+---+----
1 | 2 | 3 |
(1 row)
postgres=# update a set a2 = a;
UPDATE 1
postgres=# alter table a drop column a;
ALTER TABLE
postgres=# alter table a rename column a2 to a;
ALTER TABLE
postgres=# select * from a;
b | c | a
---+---+---
2 | 3 | 1
(1 row)
postgres=#