SET 이라는 자료형입니다. enum 과 유사하게 생겼으나 전혀 다른 별개의 자료형입니다.
enum ('a','b','c') 라고 정의된 필드가 있다고 생각합시다.
이 자료형은 a 나 b, c(혹은 null) 중 단 하나의 값을 가질수 있습니다.
set('a','b','c') 라고 정의된 필드는 enum과는 조금 다르게
null, a, b, c, (a,b), (a,c)... (a,b,c) 와 같은 값을 가질수 있습니다.
enum과는 달리 복수개의 아이템을 값으로 가질수가 있습니다.
그리고 또 하나 set 에 정의된 아이템은 비트 연산이 가능합니다.
null - 000 (0)
a - 001 (1)
b - 010 (2)
c - 100 (4)
a,b - 011 (3)
a,b,c - 111 (7)
set 형은 최대 64개의 아이템을 가질수 있고 select 문을 통해서 문자열 혹은 정수 값으로 열람이 가능합니다.
비트연산을 통해 비교구문을 활용할수 있고 그 응용범위는 넓습니다.
제 경우엔 수강신청 프로그램에 활용을 하였습니다.
각 과목은 월1~금15 까지 중 일부의 가변 갯수의 수업시간을 가집니다.
그리고 수강신청시 이미 신청한 과목과 중복된 과목은 신청할수 없겠죠?
원래는 정수형으로 필드를 설정해놓고 각 시간별로 비트를 하나씩 부여해서 php 에서 처리해주려고 했는데
이미 mysql 에 set형이라는 유사한 자료형이 있더라구요..
이 경우 기존에 수강신청한 자료에서 이미 신청한 과목의 시간을 모두 얻어
이 값을 or 연산을 해주고, 그 값과 현재 신청하려는 수강과목의 시간을 and 해주어서
그 결과가 0이 나와야 신청이 가능하겠죠??
많은 도움이 되셨나요?
SET 타입의 장점으로는
그 리스트를 bit 형 숫자 또는 문자열 모두 또는 이들 두개의 조합으로도
가능하기 때문에 잘 구성하면 테이블에서 직접 눈으로 쉽게 판별할수도 있습니다.
예를들어, 위의 경우라면,
colanme SET('1','2','3','4','5',...) DEFAULT ...
또는
colanme SET('1','2','4','8','16',...) DEFAULT ... <---- bit
또는
colanme SET('1st','2st','3st','4st','5st',...) DEFAULT ...
또는
colanme SET('a','b','c','d','e',...) DEFAULT ...
...
등등 여러가지 형태로 가능하고 실제로 이들은 내부적으로
모두 두번째 예인 비트단위로 DB 에 저장됩니다.
4번째의 경우라면
a => 1
b => 2
c => 4
d => 8
e => 16
이와같이 내부는 실제의 문자나 문자열로 연산하지 않고 오른쪽의 비트단위인 숫자로
증가하면서 저장되고 숫자형으로 비교하기 때문에 상당히 빠른다는 장점이
있습니다.
참고로, ENUM 은 1씩 증가하고 택일이지만, SET 타입은 비트 단위로 증가하고
다중선택이 가능합니다. 물론 크기는 ENUM 이 더 작습니다.
SET 타입의 자료입력은
예)
INSET INTO SET ... colname = 'a';
INSET INTO SET ... colname = 'a,b';
INSET INTO SET ... colname = 'b,a'; // 순서가 바뀌면 a,b 순서로 자동으로 저장
INSET INTO SET ... colname = 'd,e';
INSET INTO SET ... colname = 'b,c,d';
이와 같은 형식으로 자료를 입력하면 됩니다.
이들을 각각
'a' => 1
'a,b' => 1 + 2 = 3
'd,e' => 8 + 16 = 24
'b,c,d' => 2 + 4 + 8 = 14
이렇게 내부적인 비트단위로 저장되고 연산됩니다.
출력은 비트단위의 숫자가 아닌 원래의 저정한 형태의 자료형으로
출력됩니다.
검색부분에 대해서도 숫자형 BIGINT 와 같이 숫자형 연산도
가능할 뿐더러 문자열 비교도 할 수 있습니다.
BININT 같은 경우도 LIKE 와 같은 문자열 비교 연산도 가능하지만
잘못된 결과가 나올 수 있기 때문에 역시 곤란합니다.
반면 SET 타입은 문자열로도 취급가능하므로 LIKE 에 대한 잘못된
결과가 나오는 경우는 없습니다.
굳지 예를 들자면(문자형태로 저장되었을 경우),
1) 문자열로 취급할 경우
SELECT ... WHERE colname = 'a,b'; // a 와 b 만 선택한 경우
SELECT ... WHERE colname LIKE 'a%'; // 최소한 a 를 선택한 경우
SELECT ... WHERE colname IN('a','b'); // a 또는 b 만 선택한 경우
SELECT ... WHERE FIND_IN_SET('a',colname); // 최소한 a 를 선택한 경우
SELECT ... WHERE INSTR(colname,'a'); // 최소한 a 를 선택한 경우
...
2) 비트의 숫자형으로 취급할 경우
SELECT ... WHERE colname = 1; // 1 = 2^0 이므로 첫번째인 a 만 선택한 경우임
SELECT ... WHERE colname >= 1; // 최소한 a 를 선택한 경우
SELECT ... WHERE colname = 3; // 이것은 a 와 b 만 선택한 경우임
SELECT ... WHERE
3) 비트단위로 취급할 경우(bit 연산)
SELECT ... WHERE colname & 1; // 최소한 a 를 선택한 경우
SELECT ... WHERE colname & 3; // 최소한 a 또는 b를 선택한 경우(간단한 OR 연산에 이용)
이와 같이 여러가지 형태로 SQL 문을 만들 수 있다는 것이 그 장점중의 하나입니다.
'DB스토리 > MYSQL' 카테고리의 다른 글
MySQL - DB/테이블 관리 기본 명령어 (0) | 2013.11.13 |
---|---|
MYSQL 명령어 (0) | 2013.10.30 |
Mysql Workbench - Synchronize Model with Database (0) | 2013.03.18 |
Mysql Workbench 사용법 (0) | 2013.02.18 |
MYSQL 쿼리 (0) | 2013.02.05 |