Postgres에서 자연스러운 열 순서를 변경할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/126430

  •  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에서 작동하며 이전 버전과 함께 마일리지가 다를 수 있습니다.

다른 팁

데이터베이스가 크지 않고 가동 중지 시간을 감당할 수 있다면 다음을 수행 할 수 있습니다.

  1. 데이터베이스에 대한 쓰기 액세스를 비활성화합니다
    다음 지점을 시작한 후 변경된 변경 사항이 없으므로 필수적입니다.
  2. pg_dump --create --column-inserts databasename > databasename.pgdump.sql
  3. 적합한 편집 CREATE TABLE databasename.pgdump.sql의 명령문
    편집자에 비해 파일이 너무 커지면 split 명령, 편집 및 사용을 다시 조립합니다 cat
  4. drop database databasename
    당신은 최근의 백업이 있습니다.
  5. 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. 임시 이름을 사용하여 원하는 순서를 사용하여 새 버전의 테이블을 만듭니다.
  2. 기존 데이터에서 모든 데이터를 해당 새 테이블에 삽입하십시오.
  3. 오래된 테이블을 떨어 뜨립니다.
  4. 새 테이블의 이름을 "임시 이름"에서 "적절한 이름"으로 바꿉니다.
  5. 이전에 가지고 있던 모든 색인을 다시 구입하십시오.
  6. 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;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top