Loading...
MySQL 9.5 Reference Manual 9.5의 13.3.6 The ENUM Type의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
ENUM은 테이블 생성 시점에 컬럼 정의에서 명시적으로 나열된 허용 값 목록 중에서 선택되는 값을 가지는 문자열 객체입니다.
ENUM 타입의 문법과 길이 제한에 대해서는 Section 13.3.1, “String Data Type Syntax”을 참조하십시오.
ENUM 타입에는 다음과 같은 장점이 있습니다:
컬럼이 가질 수 있는 값의 집합이 제한된 상황에서 compact한 데이터 저장을 제공합니다. 입력 값으로 지정한 문자열은 자동으로 숫자로 인코딩됩니다. ENUM 타입의 저장 요구 사항은 Section 13.7, “Data Type Storage Requirements”을 참조하십시오.
읽기 쉬운 쿼리와 출력. 쿼리 결과에서 숫자는 다시 해당하는 문자열로 변환됩니다.
또한 다음과 같은 잠재적인 이슈를 고려해야 합니다:
enumeration 값을 숫자처럼 보이게 만들면, Enumeration Limitations에서 설명한 것처럼 리터럴 값과 그 내부 인덱스 번호를 혼동하기 쉽습니다.
ORDER BY 절에서 ENUM 컬럼을 사용할 때는 Enumeration Sorting에서 설명한 것처럼 추가적인 주의가 필요합니다.
Enumeration 값은 반드시 quoted 문자열 리터럴이어야 합니다. 예를 들어, 다음과 같이 ENUM 컬럼이 있는 테이블을 생성할 수 있습니다:
1CREATE TABLE shirts ( 2 name VARCHAR(40), 3 size ENUM('x-small', 'small', 'medium', 'large', 'x-large') 4); 5INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'), 6 ('polo shirt','small'); 7SELECT name, size FROM shirts WHERE size = 'medium'; 8+---------+--------+ 9| name | size | 10+---------+--------+ 11| t-shirt | medium | 12+---------+--------+ 13UPDATE shirts SET size = 'small' WHERE size = 'large'; 14COMMIT;
이 테이블에 값이 'medium'인 row를 100만 개 insert하면, 실제 문자열 'medium'을 VARCHAR 컬럼에 저장했을 때 600만 바이트가 필요한 것과 달리, 100만 바이트의 저장소만 필요합니다.
각 enumeration 값은 인덱스를 가집니다:
컬럼 정의에 나열된 element는 1부터 시작하는 인덱스 번호가 할당됩니다.
빈 문자열 에러 값의 인덱스 값은 0입니다. 이는 다음 SELECT 문을 사용하여 잘못된 ENUM 값이 할당된 row를 찾을 수 있음을 의미합니다:
1mysql> SELECT * FROM tbl_name WHERE enum_col=0;
NULL 값의 인덱스는 NULL입니다.
여기에서 말하는 “인덱스”는 enumeration 값 목록 내에서의 위치를 의미합니다. 테이블 인덱스와는 아무 관계가 없습니다.
예를 들어, ENUM('Mercury', 'Venus', 'Earth')로 정의된 컬럼은 여기 표시된 값들 중 하나를 가질 수 있습니다. 각 값의 인덱스도 함께 표시됩니다.
| Value | Index |
|---|---|
NULL | NULL |
'' | 0 |
'Mercury' | 1 |
'Venus' | 2 |
'Earth' | 3 |
ENUM 컬럼이 가질 수 있는 서로 다른 element의 최대 개수는 65,535개입니다.
ENUM 값을 수치 컨텍스트에서 조회하면, 컬럼 값의 인덱스가 반환됩니다. 예를 들어, 다음과 같이 ENUM 컬럼에서 수치 값을 조회할 수 있습니다:
1mysql> SELECT enum_col+0 FROM tbl_name;
SUM()이나 AVG()처럼 수치 인수를 기대하는 함수는 필요하다면 인수를 숫자로 캐스트합니다. ENUM 값의 경우, 계산에는 인덱스 번호가 사용됩니다.
테이블이 생성될 때, 테이블 정의에 있는 ENUM 멤버 값의 뒤쪽 공백은 자동으로 삭제됩니다.
저장된 값을 조회할 때, ENUM 컬럼의 값은 컬럼 정의에서 사용된 대소문자로 표시됩니다. ENUM 컬럼에는 문자 집합과 정렬 규칙을 지정할 수 있습니다. 바이너리 또는 대소문자 구분 정렬 규칙의 경우, 컬럼에 값을 할당할 때 대소문자가 고려됩니다.
ENUM 컬럼에 숫자를 저장하면, 그 숫자는 가능한 값에 대한 인덱스로 처리되고, 저장되는 값은 해당 인덱스를 가진 enumeration 멤버입니다. (그러나 LOAD DATA에서는 모든 입력을 문자열로 처리하기 때문에 이 방식이 동작하지 않습니다.) 수치 값이 quote로 둘러싸여 있어도 enumeration 값 목록에 일치하는 문자열이 없다면 여전히 인덱스로 해석됩니다. 이런 이유로, 숫자처럼 보이는 enumeration 값을 갖는 ENUM 컬럼을 정의하는 것은 권장되지 않습니다. 이는 쉽게 혼동을 야기할 수 있기 때문입니다. 예를 들어, 다음 컬럼은 문자열 값이 '0', '1', '2'인 enumeration 멤버를 가지지만, 수치 인덱스 값은 각각 1, 2, 3입니다:
1numbers ENUM('0','1','2')
2를 저장하면, 인덱스 값으로 해석되어 인덱스 2의 값인 '1'이 됩니다. '2'를 저장하면 enumeration 값과 일치하므로 '2'로 저장됩니다. '3'을 저장하면 어떤 enumeration 값과도 일치하지 않으므로 인덱스로 처리되어 인덱스 3의 값인 '2'가 됩니다.
1mysql> INSERT INTO t (numbers) VALUES(2),('2'),('3'); 2mysql> SELECT * FROM t; 3+---------+ 4| numbers | 5+---------+ 6| 1 | 7| 2 | 8| 2 | 9+---------+
ENUM 컬럼에 대해 가능한 모든 값을 알아내려면, SHOW COLUMNS FROM tbl_name LIKE 'enum_col'을 사용하고, 출력의 Type 컬럼에 있는 ENUM 정의를 파싱하십시오.
C API에서는 ENUM 값이 문자열로 반환됩니다. 결과 집합 메타데이터를 사용하여 다른 문자열과 구분하는 방법에 대한 정보는 C API Basic Data Structures를 참조하십시오.
특정 상황에서는 enumeration 값이 빈 문자열 ('')이나 NULL이 될 수도 있습니다:
ENUM에 (허용된 값 목록에 없는 문자열인) 잘못된 값을 insert하면, 특별한 에러 값으로서 빈 문자열이 대신 insert됩니다. 이 문자열은 수치 값이 0이라는 점에서 “일반적인” 빈 문자열과 구분할 수 있습니다. Enumeration 값에 대한 수치 인덱스에 대한 자세한 내용은 Index Values for Enumeration Literals를 참조하십시오.
strict SQL mode가 활성화되어 있으면, 잘못된 ENUM 값을 insert하려는 시도는 에러를 발생시킵니다.
ENUM 컬럼이 NULL을 허용하도록 선언된 경우, NULL 값은 컬럼에 대해 유효한 값이며, 기본값은 NULL입니다. ENUM 컬럼이 NOT NULL로 선언된 경우, 기본값은 허용된 값 목록의 첫 번째 element입니다.
ENUM 값은 컬럼 정의에서 enumeration 멤버가 나열된 순서에 따라 결정되는 인덱스 번호 기준으로 정렬됩니다. 예를 들어, ENUM('b', 'a')의 경우 'b'가 'a'보다 먼저 정렬됩니다. 빈 문자열은 nonempty 문자열보다 먼저 정렬되고, NULL 값은 다른 모든 enumeration 값보다 먼저 정렬됩니다.
ENUM 컬럼에 대한 ORDER BY 절 사용 시 예기치 않은 결과를 방지하려면 다음 기법 중 하나를 사용하십시오:
ENUM 목록을 알파벳 순으로 지정합니다.
ORDER BY CAST(col AS CHAR) 또는 ORDER BY CONCAT(col)을 사용하여 컬럼이 인덱스 번호가 아니라 사전식 순서로 정렬되도록 합니다.
Enumeration 값은 expression이 될 수 없습니다. 이는 문자열 값으로 평가되는 expression도 포함합니다.
예를 들어, 다음 CREATE TABLE 문은 CONCAT 함수를 사용하여 enumeration 값을 구성할 수 없기 때문에 동작하지 않습니다:
1CREATE TABLE sizes ( 2 size ENUM('small', CONCAT('med','ium'), 'large') 3);
사용자 변수를 enumeration 값으로 사용하는 것도 불가능합니다. 다음 문 쌍은 동작하지 않습니다:
1SET @mysize = 'medium'; 2 3CREATE TABLE sizes ( 4 size ENUM('small', @mysize, 'large') 5);
숫자를 enumeration 값으로 사용하는 것은, 적절한 TINYINT나 SMALLINT 타입에 비해 저장소 절약이 되지 않을 뿐 아니라, ENUM 값을 잘못 quote하면 문자열과 내부 수치 값(서로 다를 수 있음)을 혼동하기 쉽기 때문에 절대 사용하지 않을 것을 강력히 권장합니다. 숫자를 enumeration 값으로 사용하는 경우에는 항상 따옴표로 감싸야 합니다. 따옴표를 생략하면 숫자는 인덱스로 간주됩니다. quoted 숫자조차 수치 인덱스 값으로 잘못 사용될 수 있는 방식은 Handling of Enumeration Literals을 참조하십시오.
정의에 중복 값이 있으면 warning이 발생하며, strict SQL mode가 활성화된 경우 에러가 발생합니다.
13.3.5 The VECTOR Type
13.3.7 The SET Type