[PostgreSQL] enum type

DataBase 2010. 3. 15. 13:42



참고 : http://www.postgresql.org/docs/8.3/interactive/datatype-enum.html



PostgreSQL 에서는 일반적인 Data Type의 enum은 따로 없고, Type을 새로 생성해야 한다.
아래와 같은 형태로 Type을 생성할 수 있다.

// '울두아르', '십자군의 시험장', '얼음왕관 성채'를 데이터로 가지는 'raid_dungeon'이란 ENUM 생성
CREATE TYPE raid_dungeon AS ENUM ('울두아르', '십자군의 시험장', '얼음왕관 성채');



그리고 아래와 같은 형태로 사용한다.

// 이름과 현재 레이드 던전위치를 가지는 길드원 테이블 생성
CREATE TABLE guild_member (
    name varchar(128),
    current_position raid_dungeon
);


// 3명의 길드원 정보 입력
INSERT INTO guild_member VALUES ('오분재기', '얼음왕관 성채');
INSERT INTO guild_member VALUES ('Druman', '십자군의 시험장');
INSERT INTO guild_member VALUES ('킹크랩', '울두아르');


// 십자군의 시험장에 있는 길드원 출력
SELECT * FROM guild_member WHERE raid_dungeon='십자군의 시험장';
 name     |  raid_dungeon
---------+------------------
 Druman  | 십자군의 시험장
(1 row)




enum의 ordering은 정의된 순서에 따른다. 모든 비교연산자가 사용가능하다.
위의 데이터를 기준으로 아래처럼 동작한다.

// 십자군의 시험장보다 상위던전에 있는 길드원 출력
SELECT * FROM guild_member WHERE raid_dungeon > '십자군의 시험장';
 name     | raid_dungeon
---------+-----------------
 오분재기 | 얼음왕관 성채
(1 row)


// 울두아르보다 상위 던전에 있는 길드원을 레이드던전으로 정렬하여 출력
SELECT * FROM guild_member WHERE raid_dungeon > '울두아르' ORDER BY raid_dungeon ASC;
 name     | raid_dungeon
---------+---------------
 Druman  | 십자군의 시험장
 오분재기 | 얼음왕관 성채
(2 rows)


// 가장 낮은 던전에 있는 길드원 출력
SELECT * FROM guild_member WHERE raid_dungeon=(SELECT MIN(raid_dungeon) FROM guild_member);
 name     | raid_dungeon
---------+------------------
 킹크랩    | 울두아르
(1 row)





enum 타입은 서로 간에 완전히 분리된 형태로 구동된다. (비록 문자열 값일지라 하더라도)
그러므로 어느 enumA의 값을 enumB에 넣거나, enumA의 값과 enumB의 값의 비교는 불가능하다.

// 오리지날 레이드 던전 enum 생성
CREATE TYPE raid_dungeon_original AS ENUM ('낙스라마스', '화산심장부', '오닉시아 둥지');

// 오리지날 길드원 테이블 생성

CREATE TABLE guild_member_original (
    name varchar(128),
    current_position raid_dungeon_original
);


// 길드원 입력
INSERT INTO guild_member_original VALUES ('nicehide', '낙스라마스');
INSERT INTO guild_member_original VALUES ('드로라', '화산심장부');
INSERT INTO guild_member_original VALUES ('어네스토후스트', '오닉시아 둥지');


// 아래의 입력은 raid_dungeon_original에 없는 값이므로 에러를 발생시킨다.
INSERT INTO guild_member_original VALUES ('퀸크랩', '얼음왕관 성채');
ERROR:    invalid input value for enum raid_dungeon_original:  "얼음왕관 성채"


// 아래의 SELECT 문은 서로 다른 enum type을 비교하므로 에러를 발생시킨다.
SELECT guild_member.name, guild_member_original.name FROM guild_member, guild_member_original WHERE guild_member.current_position=guild_member_original.current_position;
ERROR:    operator does not exist: raid_dungeon = raid_dungeon_original



만약 굳이 enum 타입끼리 비교하고 싶다면 operator를 새로 만들거나 타입캐스팅을 해야한다.

SELECT guild_member.name, guild_member_original.name FROM guild_member, guild_member_original WHERE guild_member.current_position::text=guild_member_original.current_position::text;





enum 값은 디스크상에 4바이트의 공간을 차지한다.
enum 타입의 label은 컴파일 할 때 세팅한 NAMEDATALEN 값과 같다. (표준버전에서는 63바이트이다)
enum 타입의 label은 대소문자를 구분하며, 공백문자도 의미를 가진다.

'DataBase' 카테고리의 다른 글

[PostgreSQL] Date/Time Functions and Operators  (0) 2010.03.29
[PostgreSQL] pgcrypto 설치  (0) 2010.03.19
[MongoDB] with PHP  (0) 2010.03.12
[MongoDB] dbshell 레퍼런스  (0) 2010.03.12
[MongoDB] 시작, 종료  (0) 2010.03.12
Posted by bloodguy
,