#title Packed Data Type [[TableOfContents]] ==== 개요 ==== Packed Data Type이란, 일반적인 프로그래밍의 관점에서 본다면 '묶인 데이터' 쯤으로 보면 되고, 데이터베이스의 도메인에서 이야기 하자면 '복합 속성'쯤이 된다. 복합 속성은 속성이 원자값이 아닌 여러가지 값을 가지는 속성이 된다. 예를 들면, 주소, 주민번호, 학번과 같은 속성이다. 일반적으로 볼 때에 예를 들었던 속성들은 다음과 같이 쪼개질 수 있다. (필자가 아는 만큼만 대충 쪼개 보았다.) * 주소 * 시/도 * 구/군 * 동 * 상세주소 * 주민번호 * 생년월일 * 성별 * Weight Code 등 * 학번 * 입학년도 * 학과번호 * 일련번호 원자값은 해당 조직 범위의 전체적인 관점에서 볼 때에 원자값이어야 한다. 주의해야 할 점은 이렇게 쪼갠 값이 원자값은 아니라는 것이다. 원자값은 값이 더 이상 쪼개어 질 수 없는 것이 아니라 '의미의 최소 단위'를 말한다. '주소'의 경우 해당 조직에서 단지 '우편물을 보내기 위한 체계' 정도로만 필요하다면 '시/도', '구/군'등의 쪼개어진 값은 원자값이 아니다. 왜냐하면 우편물을 보내기 위해서는 '시/도', '구/군', '읍면동', '번지등의 상세주소'가 모두 포한된 것이 필요한 데이터의 최소단위이기 때문이다. 만약 마케팅팀에서 '고객에 대한 지역별로 세분화하여 특징을 파악한 뒤 지역마다 차별화된 마케팅 전략을 세운다'는 요구가 있다면 '지역별'이 어느 단위까지인지가 원자값을 정의하는 기준이 될 것이다. ==== 기본키의 중복 ==== 데이터베이스는 최소한의 중복을 지향한다. 하지만 아직까지도 중복된 속성을 Primary Key로 사용하는 곳이 많이 있다. 예를 들면 '상품번호 + 주문일 + 일련번호'와 같은 주문번호가 그것이다. 문자열로 표현하면 '099-871023-0891'과 같은 형태일 것이다. 문자열로 15Btye를 사용해야 한다. 그래서 어떤 개발자는 다음과 같은 생각을 할 수도 있을 것이다. {{{ - 상품은 200개다. 주문일은 'YYMMDD'형식이다. 각 상품당 최고 재고량은 999999이다. 하루 주문 건수는 최대 50만 건 정도다. - 상품: 1Byte, 주문일: 3Byte[* YY, MM, DD 각 1Byte], 일련번호: 3Byte - 주문번호를 7Byte로 만들면 주문테이블에 어떤 상품이 언제 또는 어떤 기간에 몇 개나 팔렸는지 주문번호 1개로 모두 알아낼 수 있을꺼야! - 그러므로 주문테이블의 상품번호, 주문일 컬럼은 삭제해도 되겠다. - 아싸! 난 천재야! }}} {{{* 날짜의 경우 bit단위로 연산을 하면 더 줄일 수 있다.DD(5bit), MM(4bit), YY(7bit) = 15bit 이므로 16bit를 사용한다고 하면 2byte면 된다.}}} 아마도 처음에는 뿌듯해 할 것이다. 하지만 시간이 지날수록 원인도 모른채 주문 테이블에 쌓여가는 Row수[* 이 시나리오라면 하루 최대 약 2억 건(200 * 999999)의 Row가 주문테이블에 쌓일 수 있다.] 만큼 사용자들의 불만도 쌓일 것이다. 이것이 여러분이 복잡하게 여러 의미를 내포하고 있는 '주문코드'나 '부서코드'의 역사적 배경이다. 어떤 경우는 주문코드만 봐도 어떤 매장에서 어떤 상품이 주문되었는지 알 수 있으므로 매우 의미있다고 할 수 있을 것이다. 하지만 이것은 오로지 '너'만 아는 것이다. 쉽지 않은 것은 데이터베이스에서는 '악'이다. (나도 계속 악행을 일삼고 있지만..) ==== 무엇이 문제인가? ==== 가장 큰 문제가 무엇 때문인가? 데이터베이스의 관점에서 볼 때는 주문번호가 '원자값'이 아니기 때문이다. 아마도 어플리케이션에서는 다음과 같은 SQL문을 DBMS에 던질 것이다. {{{#!geshi sql SELECT ... FROM 주문테이블 WHERE CONVERT(char(6), SUBSTRING(CONVERT(binary(7), 주문번호), 2, 3)) = '871021' }}} DBMS는 이 SQL문이 날아올 때마다 5천 만 건의 주문테이블을 풀스캔 할 것이다. 개발자는 87년 10월 21일의 주문 1건 조회하는데 몇 십분이 걸리냐면서 DBMS가 꾸졌다고 탓하고 있을 것이다. 데이터베이스의 특성을 이해하지 못하고, 일반적인 어플리케이션의 개발 방법을 데이터베이스에 그대로 반영한 탓일 것이다. 하지만 때로는 Packed Data Type이 데이터베이스에서도 아주 유용하게 쓰일 경우가 있다. 예를 들면, IP와 같이 DBMS에서 지원되지 않는 데이터 형식일 것이다. 대부분 문자열로 'xxx.xxx.xxx.xxx'형식으로 표현하는데, IP 1개만 조회할 경우는 괜찮으나 범위를 검색하는 경우는 아주 진상을 떨게 된다. 또 다른 예로 DW에서 골치 아픈 주제인 Surrogate Key를 이런 형태로 사용하면 유용하다. Packed Data Type이 데이터베이스에서는 부하만 유발하는 쓸모 없는 짓은 아니다. 앞서 이야기 한 것과 같은 특정 상황에서는 Packed Data Type 형태로 사용하면 쏠쏠한 재미를 볼 수 있다. 역시 정답은 없다.