본문 바로가기

🧑🏻‍💻 Dev/Database

[Postgresql] Enum 타입에 요소 추가하기

Enum 타입 조회하기


select enum_range(null::membership_enum);

 

membership_enum이라는 enum 타입을 만들어서 "FREE", "STANDARD", "DELUXE"를 저장해 놨었습니다.

여기서 만약 "VIP"라는 membership_enum 타입이 추가된다면 어떻게 요소를 추가할 수 있을까요?

 

 

 

Enum 타입에 Value 추가하기


alter type membership_enum add value 'VIP';

 

위와 같은 SQL문으로 membership_enum에 "VIP"라는 요소를 추가할 수 있습니다.

근데 만약 VIP가 사라지고, VVIP가 추가되었다면 어떻게 해야 할까요?

 

 

 

Enum 타입 Value 이름 변경하기


alter type membership_enum rename value 'VIP' to 'VVIP';

 

먼저 간단하게 위와 같은 명령어로 "VIP"를 "VVIP"로 변경해 볼 수 있습니다.

 

여기서 만약 member 테이블에서 만약 membership_enum을 필드 타입으로 가지고 있을 때는 "VIP"를 이미 값으로 가지고 있는 데이터가 있을 때는 어떻게 될까요?

지금 보면 park가 아직 membership에 VIP를 가지고 있습니다. 여기서 만약 위 SQL 명령어로 "VIP"를 "VVIP"로 이름을 바꾸면 어떻게 될까요?

membership_enum은 아무런 오류를 발생시키지 않고, 변경되어 버립니다. 이제 변경되었으면 "VIP"라는 값을 갖는 member인 "park"의 membership이 변경되었을까요?

park가 가지고 있던 VVIP가 membership이 "VIP"에서 "VVIP"로 변경되었습니다.

 

이제 만약 "VVIP"를 없애야 한다면 어떻게 해야 할까요? 기존에 "VVIP"인 고객들을 "DELUXE" 등급으로 변경하고, "VVIP"를 membership_enum에서 제거해야 합니다.

 

alter table membership_enum drop value 'VIP'가 될까요? 되지 않습니다. Postgresql에서는 Enum의 value 추가는 가능한데, 삭제가 불가능합니다.

 

사실 불편함이 없다면 기존의 membership_enum을 사용하고 "VVIP"만 사용하지 않으면 됩니다. 하지만 쓰이지도 않는 "VVIP"를 계속 놔두기도 그렇고 잘못해서 사용해서 잠재적 오류를 발생시킬 수 있습니다.

 

이때는 새로운 enum 타입을 만들어서 기존의 member.membership 타입을 변경해 주면 됩니다.

 

 

 

Enum 타입 생성하여 변경하기

create type renew_membership_enum as enum('FREE', 'STANDARD', 'DELUXE');

 

새로 변경할 Enum 타입을 생성해 줍니다. 이때 우리는 "VVIP"는 뺄 것이기 때문에 "FREE", "STANDARD", "DELUXE"만 넣어줍니다.

 

alter table member
alter column membership drop default,
alter column membership drop not null;

 

저는 기존 member 테이블의 membership 필드에 NOT NULL 제약조건과 DEFAULT 조건을 넣어두었기 때문에 이것을 제거해 줍니다.

 

alter table member 
alter column membership type renew_membership_enum
using membership::text::renew_membership_enum,
alter column membership set default 'FREE'::renew_membership_enum,
alter column membership set not null;

 

이제 member 테이블에서 membership 필드의 타입을 새로 생성한 renew_membership_enum으로 변경을 해줍니다.

 

여기서 using 하고 "membership::text::renew_membership_enum"이라는 부분이 있는데, 이것은 기존의 membership 타입의 필드를 문자열(text) 값으로 변경하고, 그 문자열을 renew_membership_enum 타입으로 형변환을 해주라는 것입니다. 그리고 이어서 바로 새로운 NOT NULL 제약조건과 DEFAULT 조건을 추가해 줍니다.

 

위 쿼리를 실행을 해보면 이렇게 오류가 뜹니다.

왜 오류가 떴는지 보면 입력된 "VVIP"는 renew_membership_enum 타입의 value가 아니라는 오류입니다. 이는 아직 우리의 member 테이블에 있는 park라는 회원이 membership 값으로  "VVIP"을 가지고 있기 때문입니다. Case When을 써서 분기를 주기도 하는 거 같은데, 저는 UPDATE 벌크 연산으로 처리를 해주겠습니다.

update member set membership = 'DELUXE' where membership = 'VVIP';

 

이제 alter table 쿼리를 실행해 보면 정상적으로 바뀐 것을 확인할 수 있습니다. 이제 사용하지 않는 기존의 membership_enum은 제거해 줍니다.

drop type membership_enum;

 

변경이 완료되었습니다!

 

 

 

 

 

 

ALTER TYPE

 

ALTER TYPE

ALTER TYPE ALTER TYPE — 자료형 정의 바꾸기 요약 ALTER TYPE 이름 OWNER TO { 새소유주 | CURRENT_USER | SESSION_USER } ALTER TYPE 이름 RENAME TO 새이름 ALTER TYPE 이름 SET SCHEMA 새스키마 ALTER TYPE 이름 RENAME ATTRIBUTE 속성

postgresql.kr

SQL query to get all values a enum can have

 

SQL query to get all values a enum can have

Postgresql got enum support some time ago. CREATE TYPE myenum AS ENUM ( 'value1', 'value2', ); How do I get all values specified in the enum with a query?

stackoverflow.com