도메인 설계

DB 설계의 핵심 중 하나다. 각 릴레이션은 어떤 속성을 가져야 하며 각 속성의 데이터형은 무엇인가와 같은 것들은 사람이 생각해서 판단하지 않으면 안 되는 분야이고 절대로 자동화 할 수 없다.

어떤 속성이 필요한지 생각할 때 결정해야 할 것은 두 가지다. 하나는 이름이고 하나는 데이터형, 도메인이다.

도메인

도메인이란

관계형 모델에서 데이터형을 말한다. 그리고 도메인의 집합으로 정의된다. 즉 도메인은 속성이 취할 수 있는 값의 집합이다. 도메인 요소에 어떤 구조를 가진 데이터를 할당할 것인지는 관계형 모델상의 제한은 없다. 컴퓨터가 표현할 수 있는 것이라면 어떤 것이든 상관없다.

집합의 요소

집합의 요소로 정의할 필요가 있으므로 명확한 값을 가진 것에 한한다. NULL이나 포인터는 집합의 요소로서 사용할 수 없으므로 도메인의 요소로 쓸 수 없다.

도메인 자신이 집합이라는 것은 해당하는 어떤 술어가 존재한다고 생각할 수 있다. 그 술어가 어떤 의미가 있는지를 생각해 두는 거로 충분하다.

도메인 설계 전략의 개요

설계는 노하우와 경험의 바탕으로 되고 단순히 논리적으로 도출되는 절대적인 정답이나 방도는 없다. 그래서 필요로 하는 것은 논리가 아니라 전략이나 철학이다.

모든 것은 자의적인 선택

각 속성에 어떤 값이 적합한지 생각하는 것은 설계자의 업무이다. 어떤 한 개의 도메인을 나타내는 방법은 한 가지뿐이 아니다. 무수히 존재하는 가능성 중 하나를 선택하는 것이다.

응용프로그램의 필요성으로 생겨난다

속성이 어떤 값을 얻을 수 있는지 결정하는 것은 응용 프로그램이다. 처음 필요한 것은 응용 프로그램에 어떤 데이터가 필요한지 인식하는 것이다. 응용프로그램이 필요로 하는 데이터를 찾아야한다. 이것은 각 도메인 설계뿐만 아니라 DB 전체 설계에도 해당한다.

적절한 DB 설계를 위해 필요한 것

적절한 DB 설계는 응용 프로그램에 관한 이해 없이는 할 수 없다. 응용프로그램의 요건이나 구현된 로직을 깊이 이해하고 있어야 그에 적합한 DB 설계를 할 수 있다.

도메인 주도 설계(Domain-Driven Design, DDD)

도메인 주도 설계는 “응용 프로그램의 본질이 무엇인가?”에 이르기 위한 설계 방법이다. 응용프로그램에 어떤 데이터나 로직이 필요한가를 알아내는 것은 DB에 어떤 릴레이션이나 속성이 필요하냐는 주제가 된다.

DB의 리팩터링

응용프로그램의 개발에는 여러 번의 리팩터링을 실시한다. 응용프로그램의 구조적인 변화가 있을 때는 DB 설계도 그에 맞게 바뀌어야한다.

데이터의 본질을 파악한다

DB는 본질적인 데이터를 처리한다

도메인을 설계할 때는 자릿수와 같은 표시상의 문제나 사용자의 편리성 등 본질적인 데이터를 확실하게 구별해야한다. DB가 다루는 것은 본질적인 데이터뿐이다. 다른 것은 응용 프로그램에 맡겨야한다. 예를 들어 학번을 표현하기 위해 숫자로만 이루어진 데이터의 도메인을 문자열로 설정한다. 이유는 8자리 학번이므로 8개가 저장되야 하기 때문이다. 이러한 것은 인쇄상의 문제나 응용 프로그램에서 바라본 설계지 DB관점에서 보는 설계로는 옳지 않다

속성(칼럼)의 이름

명명 규칙 통일, 주어 포함 외에도 다른 것이 있다. 가장 중요한 점은 속성이 나타내는 데이터의 본질을 표현하는 이름을 사용하는 것이다. 즉, 이름은 본문을 나타내는 속성명이어야 한다. 응용프로그램에서 사용되는 클래스명이나 변수명과 같은 이름을 사용하도록 하고, 만일 응용프로그램에서 클래스명이나 변수명을 리팩터링했다면 DB 쪽도 동기화 하도록 하자.

ID 설계 개념

현실 세계와 물체나 개념을 나타내는 수단

DB에 저장된 ID는 현실 세계의 물체나 개념을 나타낸다. 물체나 개념을 집합으로 표현하는 것이 관계형 모델의 기본 개념이다. 현실 세계에서는 물건과 속성이 1대1로 일치하는 모습을 볼 수 있다. 1:1 관계는 집합론의 용어로 전단사 함수라고 한다. 이처럼 정확하게 1대1로 일치하는 관계가 되지 않으면 ID로 기능하지 않는다.

ID를 설계하는 경우는 그것이 개체에 대한 것인지 집단에 대한 것인지, 집단이라면 어떤 크기로 집합을 식별화할지 등을 고려해야한다. 혹은 의제영역이 한정된 경우라면 세상에서 유일성을 갖지 않는 꼬리표라도 ID로 기능할 수 있다. ID가 유일성을 가진 꼬리표로써 사용할 수 있는지 아닌지는 설계하기 나름이다. 인간이 고유하게 설계해 ID가 ID로서 기능을 하는 것이다.

자연키와 대체키

자연키란 세상에 존재하는 어떤 단어나 꼬리표를 키로 사용하는 것이다. 대리키는 이 세상에는 없고 DB또는 DB를 사용하는 응용프로그램 내부에서만 통용되는 ID다.

어느쪽을 선택해야 하는가

자연키가 가장 바람직할 수 있지만 중복될 가능성이 있다. 예를 들어 사람이름의 경우 얼핏보면 유일성을 가져 키가 될 수 있지만 이름은 중복이 될 수 있으므로 키로 사용할 수 없다. 설령 알려진 자연키가 현재로서는 키로서 역할을 할지 몰라도 이후에 규모가 커질수록 키의 기능을 상실할 수 있는 경우 해당 칼럼은 자연키로 설정할 수 없다. 그렇다고 모든 것을 대체키로 설정하는 것은 옳지 않다. 현실 세계의 물건이나 개념과 1:1로 대응하는 집합이라면 자연키를 사용해도 문제는 없다. 문제가 되는 것은 판단이다.

자연키의 사용 대상과 문제점

자연키 자체를 사용하는 것은 문제가 되지 않는다. 문제는 ID로서 기능을 사용할 수 있는지이다. 예를 들어 도서의 ISBN의 경우 구판과 신판 모두 같은 ISBN을 사용하는 경우가 있고 그렇지 않은 경우도 있다. 이럴경우 ID로서 사용할 수 없게된다. 또한 무엇을 특정하는 것인지도 중요하다. 이메일 주소는 유일하기 때문에 식별이 가능하지만, 사람을 특정하는 것이 아니다. 사람과 이메일은 1:1로 일치하지 않는다. 사용자 ID를 표현하는데 이메일 주소를 자연키로 사용하는 것은 위험하다. 그 값이 무엇을 특정하는 것인지 생각해야 한다.

대체키의 사용 대상과 문제점

시스템적으로 ID를 써서 사용하는 것은 문제가 없다. 문제는 이미 자연키가 있는데 대체키를 새로 만드는 경우다. 새로운 대체키를 만들어도 본래의 자연키에는 유니크 제약이 필요하다. SQL은 해당 테이블을 갱신하면 유니크 키를 갱신하기 위한 오버헤드가 발생한다. 인덱스 갱신을 위한 오버헤드가 높아지므로 불필요한 인덱스는 가능한 한 작성하지 않는다. 만일 유니크키를 없애버린다면 중복이 발생할 위험이있고 오버헤드가 발생할 것이다. 이미 적절한 자연키가 존재할 때는 본질적으로 대체키가 불필요하다.

관계형 모델의 키

자연키나 대체키는 관계형 모델 개념에 없다. 후보키와 슈퍼키 뿐이고 키라는 기능은 단순히 튜플에 포함된 속성의 값을 유일하게 결정할 수 있다는 것에 지나지 않는다. 키가 자연키이든 대리키이든 관계형 모델을 기반으로 한 설계 논리에 적용할 수 있다.

의미가 있는 ID

아이디 자체에 의미가 있는 경우이다. 어떠한 제품의 상태에 따라 “XXXX-AAAA-BBBB-OOOO”와 같은 형식의 제품번호를 가지는 것을 본 적이 있을 것이다. 이러한 ID의 경우 각 자리마다 의미가 있는 단어의 조합이 되고는 하는데 만일 XXXX로 시작하는 제품을 찾으려면 SELECT * FROM TABLE WHERE ID LIKE 'XXXX%'로 시작해야 한다. 이는 1NF가 되지 않아서 그렇다. ID에 사용된 요소들을 여러개로 나눌 수 있다면 각 속성으로 정의하는 것이 좋다. 그러나 만약 여러개의 칼럼이 키가 성립할 때는 대체키로 사용하는 것이 나쁘지 않다. 그래도 ID 일부에 의미를 부여하는 설계는 피해야 한다.

색, 길이, 무게 등을 나타내는 속성

[추가예정]

SQL로 도메인 표현

적절한 데이터형 선택

도메인 자체와 SQL의 각종 데이터형은 1:1로 대응하지 않지만 도메인이 가지는 값을 모두 포함할 수 있는 데이터형을 선택해야 한다. 수치라면 충분한 자릿수가 있는지 문자열이라면 충분한 길이를 가지는지 고려해야 한다. 수치형 데이터를 문자열로 표현하는 경우에는 문제점이 있다. 불필요하게 테이블 사이즈가 커지고, 수치 최에 문자도 저장할 수 있어야 하고, 숫자로 연산할 수 없는 등의 이유가 있다.

술어를 제약으로 표현

칼럼이 도메인의 특징을 잘 표현하려면 도메인과 그 칼럼의 데이터형이 1:1 관계로 전단사(중복 없이 1:1로 대응시키는 함수)되어 있는 것이 바람직하다. 도메인과 칼럼의 대응을 단사에 가깝게 하는 방법으로 CHECK 제약 조건을 들 수 있다.

Check 제약 조건이란? 입력되는 값을 체크하여 설정된 값 이외의 값이 들어오면 오류 메시지와 함께 명령이 수행되지 않는 것을 말한다.

그러나 이렇게 전단사 되는 것은 이상적이지만 모든 칼럼에 이런 제약을 거는 것은 현실적이지 않다. 제약이 늘어나면 오버헤드가 커지게 된다.

도메인을 테이블로 표현

도메인이 열거형이면 다른 테이블에 미리 도메인에 포함된 모든 값을 저장해 두는 방법이 있다. 이런 테이블을 마스터 테이블이라고 한다. 도메인은 집합이므로 술어로 정의하지 않고 마스터 테이블 내에 실 데이터를 열거하는 형태로 정의해도 된다.

출처

원리부터 배우는 관계형 데이터베이스 실전 입문/오쿠노 미키야 지음/성창규 옮김