Postgres에서 자연스러운 열 순서를 변경할 수 있습니까?
-
02-07-2019 - |
문제
Postgres 8.1에서 기둥의 자연 순서를 변경할 수 있습니까?
열 순서에 의존해서는 안된다는 것을 알고 있습니다. 필수적인 내가하고있는 일에 - 나는 더 유쾌한 방식으로 자동 생성 된 물건을 나오기 위해서만 필드 주문이 Pgadmin에서 백엔드까지, 프론트 엔드까지 일치하도록하기 만하면됩니다.
해결책
실제로 열 순서를 바로 변경할 수는 있지만 권장하지 않으며, 그렇게하기로 결정한 경우 매우 조심해야합니다.
예를 들어.
# CREATE TABLE test (a int, b int, c int); # INSERT INTO test VALUES (1,2,3); # SELECT * FROM test; a | b | c ---+---+--- 1 | 2 | 3 (1 row)
까다로운 비트의 경우 Postgres 사용자를 사용하여 데이터베이스에 연결하여 시스템 테이블을 수정해야합니다.
# SELECT relname, relfilenode FROM pg_class WHERE relname='test'; relname | relfilenode ---------+------------- test_t | 27666 (1 row) # 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 rows)
Attnum은 고유 한 열이므로 열 번호를 수정할 때는 임시 값을 사용해야합니다.
# UPDATE pg_attribute SET attnum=4 WHERE attname='a' AND attrelid=27666; UPDATE 1 # UPDATE pg_attribute SET attnum=1 WHERE attname='b' AND attrelid=27666; UPDATE 1 # UPDATE pg_attribute SET attnum=2 WHERE attname='a' AND attrelid=27666; UPDATE 1 # SELECT * FROM test; b | a | c ---+---+--- 1 | 2 | 3 (1 row)
다시 말하지만, 이것은 데이터베이스 시스템 테이블과 함께 재생되기 때문에 실제로해야한다고 생각되면 매우주의를 기울이십시오.
이것은 Postgres 8.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 11의 경우에도 여전히 사실입니다.
언급 된 다른 답변에 따르면, 열 순서를 변경할 수는 없습니다. 당신은 견해로 문제를 해결할 수 있습니다. 보고 쿼리의 목적 상, 테이블처럼 보입니다. 같은 것 :
create view my_view as
select * from my_table
order by some_col;
쿼리에서 열 순서를 지정하는 것은 유일한 신뢰할 수있는 (그리고 제정신) 방법입니다.. 즉, 열이 일반적으로 테이블에 추가 된 순서대로 반환되므로 아래 예제에 표시된대로 테이블을 변경하여 일반적으로 다른 순서를 얻을 수 있습니다.
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=#
불행히도, 아니, 그렇지 않습니다. 열 순서는 전적으로 포스트 그레에 달려 있습니다.
새 테이블을 만들고 기존 테이블의 열을 선택하여 원하는 열 순서를 얻을 수 있습니다.
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;
나는 똑같이 원한다. 예, 지금 필수적으로 주문하지만 잘못된 길을 문지릅니다 :)
내가 해결하기 위해하고있는 일은 다음과 같습니다.
이 방법은 기존 데이터를 유지하고
- 임시 이름을 사용하여 원하는 순서를 사용하여 새 버전의 테이블을 만듭니다.
- 기존 데이터에서 모든 데이터를 해당 새 테이블에 삽입하십시오.
- 오래된 테이블을 떨어 뜨립니다.
- 새 테이블의 이름을 "임시 이름"에서 "적절한 이름"으로 바꿉니다.
- 이전에 가지고 있던 모든 색인을 다시 구입하십시오.
- 1 차 키 증가에 대한 ID 시퀀스를 재설정합니다.
현재 테이블 순서 :
id, name, email
1. 임시 이름을 사용하여 원하는 순서를 사용하여 새 버전의 테이블을 만듭니다.
이 예에서는 원합니다 email
전에 name
.
CREATE TABLE mytable_tmp
(
id SERIAL PRIMARY KEY,
email text,
name text
);
2. 모든 데이터를 기존 테이블에서 해당 새 테이블에 삽입하십시오.
INSERT INTO mytable_tmp --- << new tmp table
(
id
, email
, name
)
SELECT
id
, email
, name
FROM mytable; --- << this is the existing table
3. 오래된 테이블을 떨어 뜨립니다.
DROP TABLE mytable;
4. 새 테이블의 이름을 "임시 이름"에서 "적절한 이름"으로 바꿉니다.
ALTER TABLE mytable_tmp RENAME TO mytable;
5. 이전에 가지고 있던 모든 색인을 다시 구입하십시오.
CREATE INDEX ...
6. 1 차 키 증가에 대한 ID 시퀀스를 재설정합니다.
SELECT setval('public.mytable_id_seq', max(id)) FROM mytable;