9장 메타데이터 트리블

작업을 단순하게 하기 위한 데이터베이스 설계로 인해 문제를 야기할 수 있다.
이 예제에서는 특정 우수고객을 추적하기 위해 년도별 매출액 정보를 관리하기 위해 해당 속성을 매년을 추가하므로 발생하는 문제를 논하게 된다.

9.1 목표 : 확장 적응성 지원

데이터의 양이 늘어나면 어떤 데이터베이스 쿼리든 성능이 떨어진다.
목표는 쿼리 성능을 향상시키고 지속적으로 크기가 늘어나는 테이블을 지원하도록 데이터베이스를 구성하는 것이다.

9.2 안티패턴 : 테이블 또는 컬럼 복제

모든 테이블이 보다 적은 행을 포함하도록 만들어야 한다는 그릇된 생각이 두 가지 형태의 안티패턴으로 나타난다.

  • 많은 행을 가진 큰 테이블을 여러 개의 작은 테이블로 분리한다. 작은 테이블은 테이블의 속성 중 하나의 값을 기준으로 짓는다.
  • 하나의 컬럼을 여러 개의 컬럼으로 분리한다. 컬럼의 이름은 다른 속성의 값을 기준으로 짓는다.
테이블이 우글우글
  • 데이터를 분리해 별도의 테이블을 나누게 되면 입력삭제에 대한 핸들링을 사용자가 전적으로 책임져야 한다.
  • 분리된 테이블에 새로운 값이 들어가야 한다면 새로운 테이블을 미리 만들어 두지 않으면 안된다.
데이터 정합성 관리

테이블이름에 따라 데이터를 자동으로 제한 할 수 있지만 별도의 체크Constraint가 필요할 수 있다. 테이블이 만들어 질 때마다 이 체크조건에 주의를 기울여야 한다.

데이터 동기화

잘못된 데이터를 수정하려는데 다른 테이블에 반영해야 한다면? 간단히 업데이트를 하지 못 하고삭제 후 해당 테이블에 삽입해주어야 한다.

유일성 보장

하나의 테이블의 값을 다른 범위의 테이블로 옮길 경우 PK가 충돌되지 않는다는 확실한 보장이있어야 한다. 이를 위해 전역적으로 사용할 수 있는 시퀀스를 사용하거나 PK생성을 위한 테이블이 필요할 수 있다.

여러 테이블에 걸쳐 조회하기

시간이 흘러감에 따라 테이블이 계속적으로 증가하게 되면 이를 참조하는 SQL를 계속 수정해야 한다.

메타데이터 동기화

분리된 여러 개의 테이블이 시간이 지나면서 서로 다른 컬럼을 가지게 된다면 UNION을 이용하여 묶을 때 와일드카드가 아닌 컬럼 리스트를 나열해야 한다.

참조 정합성 관리

분리된 테이블을 참조하는 자식테이블이 있다면 FK설정을 하지 못하게 된다. 동일한 컬럼에 대해서 여러 개의 부모테이블을 참조할 수 없기 때문이다.

메타데이터 트리블 컬럼 식별하기

다음과 같은 컬럼에서 bugs_fixed_2010 컬럼추가가 필요한 시기는 이미 도래했나?


CREATE TABLE ProjectHistory (
  bugs_fixed_2008  INT,
  bugs_fixed_2009  INT,
  bugs_fixed_2010  INT
);

9.3 안티패턴 인식방법

  • 그러면 우리는 ~당 테이블(또는 컬럼)을 생성해야해
    : "~당"에 나오는 값으로 테이블(또는 컬럼)이 분리된 것이다.
  • 이 데이터베이스에 테이블을 최대 몇 개까지 만들 수 있을까?
    : 최대허용치를 초과할 것 같은 생각이 든다면, 설계를 재고할 필요가 있다.
  • 오늘 아침에 어플리캐이션이 새로운 데이터를 추가하는데 실패한 이유를 알아냈어 새해에 대한 테이블을 만드는 것을 까먹었지 뭐야.
    : 메타데이터 트리블이 사용되었 때 나타나는 흔한 현상
  • 어떻게 하면 여러 테이블을 한꺼번에 검색하는 쿼리를 작성할 수 있을까? 모든 컬럼은 모든 테이블을 가지고 있어
    : 동일 구조를 가진 테이블 여러 개를 한꺼번에 검색할 일이 많다면, 하나의 테이블로 저장
  • 어떻게 하면 테이블 이름을 파라미터로 넘길 수 있을까? 테이블 이름 뒤에 연도를 동적으로 붙여서 쿼리를 해야 해.
    : 한 테이블에 있다면 그럴 필요가 없다.

9.4 안티패턴 사용이 합당한 경우

매일 사용하는 데이터와 오래된 데이터를 분리해 별도 보관해야 할 경우.

9.5 해법 : 파티션과 정규화

테이블이 매우 커졌을 때 수평분할/수직분할/종속 테이블을 사용하는 방법이 있다.

수평분할 사용

수평분할(horizontal partitioning)기능은 큰 테이블을 분리했을 때 장점만 살릴 수 있다.
여러 행을 파티션으로 분리하는 규칙과 함께 논리적인 테이블을 하나 정의하면 된다.
각각의 그룹을 별도 스토리지에 분리할 수 있는 방법도 제공한다.

수직분할 사용

수직분할(vertical partitioning)은 컬럼으로 테이블을 나누는데 크기가 큰 컬럼(LOB)이나 거의 사용되지 않는 컬럼이 있을 때 유리하다.
나누고자 하는 큰 컬럼을 종속테이블로 생성하여 이 테이블에 LOB타입이나 자주 사용되지 않는 컬럼을 저장하고 원본 테이블의 하나 당 1행만 존재하도록 PK를 FK로 생성하다.

  • 최초작성일 : 2011년 12월 06일
  • 이 문서는 오라클클럽 코어 오라클 데이터베이스 스터디 모임에서 작성하였습니다.
  • {*}이 문서의 내용은 인사이트(insight) 에서 출간한 'SQL AntiPatterns : 개발자가 알아야 할 25가지 SQL 함정과 해법'를 참고하였습니다.*