이는 바이너리로 구성된 포맷이나 프로토콜에서 전달되는 데이터의 용량을 줄여 압축적으로 데이터를 전달하기 위해 사용되는 경우가 대부분이지만 현업에서 데이터베이스를 접하다보면 비트마스크를 활용하여 하나의 필드에 여러가지 의미를 담아놓은 필드를 발견하는 순간이 있다.
예를 들어 식당을 저장한 테이블이 존재하고 각각의 식당은 업종에 대한 코드값을 가지고 있다고 생각해보자.
- 사천마라탕 (중식)
- 파스타하우스(양식)
- 닌자초밥(일식)
- 그루브하우스 (카페, 양식)
업종 코드 테이블
코드값 | 의미 |
1 | 중식 |
2 | 양식 |
4 | 일식 |
8 | 카페 |
식당 테이블
식당 이름 | 업종 코드 |
사천마라탕 | 1 |
안동소고기국밥 | 2 |
닌자초밥 | 4 |
그루브하우스 | 10 |
먼저 업종코드 테이블은 2의 배수 형태로 데이터를 저장하고 있고,
식당 테이블에서 그루브하우스를 확인하면, 업종코드테이블에 존재하지 않는 10이라는 값으로 데이터가 저장되어 있다.
이 때, 12라는 의미는 비트마스킹의 개념을 도입한 필드로 볼 수 있다.
양식에 해당되는 값인 2와 카페에 해당되는 8값을 더하여 10이라는 값으로 표현된 것이다.
- 그루브하우스(10) = 양식(2) + 카페(8)
예를들어 하나의 식당에서 모든 업종에 포함되는 메뉴를 제공한다고 가정하면 코드값은 17이라는 값을 가지게 된다.
- 메가식당(17) = 중식(1) + 양식(2) + 일식(4) + 카페(8)
아래와 같이 어떤 코드값의 조합을 하더라도 기존의 코드값을 침해하지 않는 것을 확인할 수 있다.
업종 코드 | 실제 업종 |
1 | 중식 |
2 | 양식 |
3 | 중식 + 양식 |
4 | 일식 |
5 | 중식 + 일식 |
6 | 양식 + 일식 |
7 | 중식 + 양식 + 일식 |
... | ... |
비트 마스킹 필드를 사용하는 것의 단점은 아래와 같은 것들이 존재한다.
- 업종코드 테이블과 식당 테이블을 물리적인 관계를 생성할 수 없다.
- 업종을 기준으로 데이터를 조회할 때 비트 연산이나 IN 쿼리를 통한 범위 질의를 수행해야만 한다.
비트 연산을 할 경우 인덱스 사용이 불가하여 성능의 저하가 발생하게 되고,
IN 쿼리를 통한 질의를 할 경우 쿼리의 복잡도가 매우 상승할 수 있다.
-- 양식(2)에 해당하는 레코드를 가져오게 될 때
SELECT *
FROM [식당 테이블]
WHERE [업종 코드] & 2 = 2
--> 좌변에 비트 연산을 해야 하므로 인덱스 사용이 불가하여 성능이 저하된다.
SELECT *
FROM [식당 테이블]
WHERE [업종코드] IN (2, 3, 6, 7, 10, 11, 15)
--> 업종코드의 비트 연산을 머리속으로 계산하여 IN 연산을 수행할 경우 쿼리의 복잡도가 높아진다.
--> 실수를 발견하기가 매우 여럽다.
다만, 현업에서 비트 마스킹 필드를 사용하는 이유는 아래와 같은 장점이 존재하기 때문이다.
- 기존의 스키마 변경 없이 코드값의 변경으로 문제를 해결 할 수 있다.
위와 같은 문제를 해결하려면, 테이블이나 필드를 분해하는 대규모 수정 작업을 수행해야 하므로 많은 시간이 소요되는 작업이다.
가장 올바른 해결책은
- 코드의 개수가 작다면 각각의 코드를 필드로 분해하는 것이 타당하다.
- 코드의 개수가 많다면 [식당-업종 테이블]과 같이 [식당 테이블]과 [업종 테이블]을 연결하는 테이블로 분해하는 것이 타당하다.
하지만, 개발자에게 시간은 한정적이며, 문제 해결이 시급한 순간들이 존재한다. 이 때 비트마스크 필드를 활용하여 빠르게 문제 상황을 해결하고 이 후 시간적 여유를 가지고 수정 작업을 수행하는 것도 하나의 방법이 될 수 있을 것이라고 생각한다.
'DBMS > SQL-SERVER' 카테고리의 다른 글
SQL Server 기본키 없이 인덱스가 존재할 때 (0) | 2020.11.17 |
---|---|
SQL-Server 테이블을 텍스트로 출력(BCP) (0) | 2020.11.11 |
SQL-Server 성능 최적화 (tempdb) (0) | 2020.11.04 |
SQL Server(MS-SQL) 날짜 및 시간의 변경 방법(datetime) (0) | 2020.10.29 |
SQL Server(MS-SQL) 현재 날짜와 시간 가져오기 (0) | 2020.10.24 |