오늘은 소설입니다.
sun's longitude:239 53 40.28 
· 자유게시판 · 묻고답하기 · 알파문서 · RPMS list
· 사용자문서 · 팁/FAQ모음 · 리눅스Links · 자료실
· 서버정보 · 운영자 · Books/FAQ · FreeBSD
/board/delete.php:소스보기  
알파문서
자주 잊어먹거나, 메모해 둘 필요성이 있는 팁이나 문서, 기타 등등
[*** 쓰기 금지단어 패턴 ***]
글 본문 중간에 업로드할 이미지를 추가하는 방법 : @@이미지이름@@
ex) @@foo.gif@@
 ★ 글 지우기 항목입니다. 한번 더 생각하시고 결정하십시오.!!!
제목 60 : [MySQL] SET type 에 관한 사용법
 이름  산이 [홈]http://linuxchannel.net/
우선,
컬럼이 50정도면 용도나 보는 기준에 따라 다르겠지만
크다고 말할수도 없습니다.
물론 웹게시판과 비교하면 당연히 크지만 대용량 DB 같은
경우에는 결코 크다고 말할수는 없습니다.

테이블을 쪼개었을 경우 join 으로 다시 묶어줄 경우
서버의 부담이 크거나 긴 한번의 쿼리보다는 두번의 쿼리가
더 나쁠경우에는 비록 그 컬럼수가 50이 넘더라도
하나의 테이블에 담아야 하는 경우가 있습니다.

물론 bit 정도라면 대용량이더라도 굳지 여러개의 컬럼을
사용할 필요는 없겠지요.
미밍님이 올린내용대로 하나의 컬럼으로 사용하면 될것 같군요.

우선 이 문제는 핵심에서 떨어진 문제이므로 접어두고,

WHERE $bin_search = (fieldname & $bin_search)

이 쿼리 부분을

WHERE fieldname & $bin_search
또는
WHERE (fieldname & $bin_search) > 0

이렇게 해도 됩니다.

그리고, sh. 님과 같이 set 타입을 사용하면 여러가지 장점을
살릴수 있습니다.

--------------------------------------------
(초보자를 위해서 조금 길게 적었습니다.)
----------------------------------------------

우선

100 과 같은 비트단위는 문자형 타입으로 결정하려면
CHAR(50) 또는 VARCHAR(50) 으로 지정해야 하는데 크기가 50 Bytes라서
부적절합니다.

반면 숫자형 타입으로 결정하려면 BIGINT(50) UNSIGNED ZEROFILL 으로
해야하는데 이때는 크기가 8 Bytes 입니다.
(INTEGER 로서는 2^50 = 1,125,899,906,842,624 의 크기를 모두 담을 수 없습니다.)
참고로 BIGINT 는 최대 2^63 까지 가능합니다.

숫자형 타입으로 또한 DOUBLE 형도 가능하는데 이들
숫자형 타입은 모두 좀 알아보기가 힘들다는 단점이 있습니다.

따라서 제일 적절한 타입은 SET 타입으로 64개의 리스트 즉,
최대 2^64 이라는 경우의 수를 만들 수 있습니다.
크기는 숫자형타입과 마찬가지로 리스트 개수(L) 이 32 < L < 64 이면
8 Bytes 입니다.

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 문을 만들 수 있다는 것이 그 장점중의 하나입니다.
2003년 09월 19일 02:13:24 금(새벽)  from 61.254.75.40
0
암호: 공용 보안 SSL 서버가 준비되기 전까지는 off 합니다

apache lighttpd linuxchannel.net 
Copyright 1997-2024. linuxchannel.net. All rights reserved.

Page loading: 0.01(server) + (network) + (browser) seconds