SQL 개발자(SQLD)

SQL 개발자(SQLD) 시험 노트개념 정리18 MIN

식별자와 본질식별자·인조식별자

SQLD 1과목의 넷째 자리입니다. 주식별자의 네 가지 특징과 대표성·생성 주체·구성 수에 따른 분류, 식별관계와 비식별관계를 가르는 기준, 그리고 인조식별자를 붙였을 때 생기는 부작용까지 정리합니다.

앞 노트에서 관계가 외래키로 내려앉는 과정을 봤습니다. 그 외래키가 무엇을 복사해 온 것인지, 그리고 복사해 온 것을 자기 식별자에 포함할지 말지가 이 노트의 주제입니다. 식별자는 1과목에서 두 문항 안팎이 나오는데, 마지막 절의 인조식별자는 정답 자체보다 「왜 나쁜가」를 묻는 형태라 이유를 함께 외워야 합니다.

식별자의 조건

식별자는 엔터티의 인스턴스를 유일하게 구분하는 속성 또는 속성의 조합입니다. 논리 모델의 용어이고, 물리 모델로 내려가면 기본키(Primary Key)가 됩니다.

주식별자의 네 가지 특징

특징 뜻 어겼을 때
유일성 인스턴스를 유일하게 구분한다 같은 값의 행이 둘 생긴다
최소성 유일성을 만족하는 최소의 속성 수로 구성한다 없어도 되는 컬럼이 키에 끼어 인덱스가 커진다
불변성 한 번 정해지면 값이 바뀌지 않는다 자식 테이블의 외래키를 전부 따라 고쳐야 한다
존재성 값이 반드시 존재한다. NULL일 수 없다 식별할 수 없는 행이 생긴다

네 가지 중 불변성이 가장 자주 걸립니다. 주민등록번호나 이메일 주소는 유일해 보여도 바뀔 수 있고, 실제로 바뀌면 그 값을 외래키로 들고 있는 모든 테이블을 함께 갱신해야 합니다. 「유일하면 주식별자로 쓸 수 있다」는 보기가 나오면 틀린 것입니다 — 넷을 다 만족해야 합니다.

주식별자를 고르는 기준

특징 넷을 통과한 후보가 여럿이면 실무 기준으로 고릅니다. 업무에서 실제로 그것을 불러 쓰는 속성을 고르고(사원번호를 쓰지 이름+생년월일을 쓰지 않습니다), 이름처럼 자주 수정되는 속성은 피하며, 구성 속성 수는 적을수록 좋습니다. 복합 식별자가 되면 그 키를 물려받는 자식 테이블마다 컬럼이 그만큼 늘어나기 때문입니다.

식별자의 분류

같은 식별자를 세 축으로 나눕니다. 축이 셋이므로 「주식별자이면서 내부식별자이면서 복합식별자」 같은 조합이 얼마든지 가능합니다.

대표성에 따라

종류 뜻
주식별자 엔터티를 대표하는 식별자. 다른 엔터티와 관계를 맺을 수 있다
보조식별자 인스턴스를 구분할 수는 있지만 대표성이 없어 관계를 맺지 못한다

사원 엔터티에서 사원번호가 주식별자라면, 유일하지만 대표로 쓰지 않는 이메일 주소는 보조식별자입니다. 관계를 맺을 수 있는 쪽은 주식별자뿐이라는 것이 이 분류의 핵심입니다.

생성 주체에 따라

종류 뜻 예
내부식별자 그 엔터티 안에서 스스로 만들어진다 주문 엔터티의 주문번호
외부식별자 다른 엔터티에서 받아 온다 주문 엔터티의 고객번호

외부식별자가 곧 물리 모델의 외래키입니다. 앞 노트에서 본 대로 1:M 관계에서 1 쪽의 주식별자가 M 쪽으로 복사되면서 생깁니다.

구성 속성 수에 따라

속성 하나로 식별하면 단일 식별자, 둘 이상을 묶어야 식별되면 복합 식별자입니다. 주문상세가 「주문번호 + 상품번호」로 식별되는 것이 복합 식별자이고, 이런 자리는 대개 M:N을 푼 행위 엔터티입니다.

세 축은 서로를 배제하지 않습니다. 주문상세의 「주문번호 + 상품번호」는 대표성으로 보면 주식별자, 생성 주체로 보면 두 외부식별자의 조합, 구성 수로 보면 복합 식별자입니다. 하나의 식별자를 세 번 다르게 부른 것이라, 「외부식별자는 주식별자가 될 수 없다」 같은 보기는 축을 섞어 만든 틀린 문장입니다.

식별관계와 비식별관계

부모의 주식별자를 받아 온 자식이 그것을 자기 주식별자에 넣는지로 관계가 갈립니다. 물려받는다는 사실은 같고, 물려받은 것을 어디에 두는지가 다릅니다.

두 관계의 차이

견줄 것 식별관계 비식별관계
부모 식별자의 자리 자식의 주식별자에 포함 자식의 일반 속성
자식의 존재 부모가 있어야만 존재 부모 없이도 존재 가능
필수 여부 필수(NULL 불가) 대개 선택(NULL 허용)
ERD 표기 실선 점선
-- 식별관계: 주문번호가 주문상세의 주식별자 일부다
CREATE TABLE 주문상세 (
  주문번호 NUMBER,
  상품번호 VARCHAR2(20),
  수량     NUMBER,
  PRIMARY KEY (주문번호, 상품번호),
  FOREIGN KEY (주문번호) REFERENCES 주문(주문번호)
);

-- 비식별관계: 고객번호는 주문의 일반 속성이다
CREATE TABLE 주문 (
  주문번호 NUMBER PRIMARY KEY,
  고객번호 NUMBER REFERENCES 고객(고객번호),
  주문일자 DATE
);

어느 쪽을 고를 것인가

식별관계로만 이으면 키가 계속 길어집니다. 손자·증손자로 내려갈 때마다 조상의 키가 전부 쌓여, 4대째쯤 되면 주식별자가 컬럼 다섯 개짜리가 됩니다. 비식별관계로만 이으면 조인이 늘어납니다. 손자에서 조상의 값으로 검색할 때 중간 테이블을 전부 거쳐야 하기 때문입니다.

그래서 기준은 이렇습니다 — 자식이 부모 없이 존재할 수 없고 부모의 키로 자주 조회한다면 식별관계, 자식이 독립적으로 존재하거나 키가 너무 길어진다면 비식별관계입니다. 「무조건 어느 쪽이 좋다」는 보기는 항상 틀린 보기입니다.

본질식별자와 인조식별자

같은 엔터티를 두고 「업무가 이미 갖고 있는 것으로 식별할 것인가, 우리가 새로 만들어 붙일 것인가」를 정하는 자리입니다. 앞의 세 축과 달리 이것은 분류가 아니라 설계 판단이라, 시험도 이름 맞히기보다 결과를 묻습니다.

본질식별자

본질식별자는 업무에서 그 인스턴스를 실제로 구분하는, 업무적 의미가 있는 식별자입니다. 주문상세를 「주문번호 + 상품번호」로 식별하는 것이 본질식별자입니다 — 같은 주문 안에서 같은 상품이 두 줄일 수 없다는 업무 규칙이 그 안에 들어 있습니다.

본질식별자의 장점은 제약이 공짜로 딸려 온다는 것입니다. 그 조합을 주식별자로 잡아 두면 데이터베이스가 중복을 막아 주므로 애플리케이션이 따로 검사할 필요가 없습니다. 단점은 길이입니다. 업무 규칙이 복잡할수록 조합이 길어지고, 그 키를 물려받는 자식마다 컬럼이 함께 늘어납니다.

인조식별자와 그 부작용

인조식별자는 본질식별자가 복잡하거나 길 때 일련번호 같은 것을 새로 만들어 붙인 식별자입니다. 주문상세에 주문상세ID를 시퀀스로 붙이는 식입니다. 관리가 편해 널리 쓰지만 대가가 있습니다.

부작용 무슨 일이 생기나
중복 데이터 발생 본질식별자에 걸려 있던 유일성이 풀려 같은 조합이 여러 행 들어간다
불필요한 인덱스 생성 인조키 인덱스와 본질 컬럼 인덱스를 둘 다 만들게 된다
조인 시 본질 컬럼 누락 인조키만 보고 조인해 업무적으로 맞는 조건을 빠뜨린다
의미 없는 값 값만 보고는 어떤 데이터인지 알 수 없어 추적이 어렵다

첫 줄이 가장 큽니다. 「주문번호 + 상품번호」가 주식별자일 때는 데이터베이스가 중복을 막아 주지만, 인조키로 바꾸면 그 제약이 사라져 같은 주문에 같은 상품이 두 줄 들어갑니다. 인조식별자를 쓸 때는 본질식별자 조합에 유니크 제약을 따로 걸어야 합니다.

CREATE TABLE 주문상세 (
  주문상세ID NUMBER PRIMARY KEY,          -- 인조식별자
  주문번호   NUMBER NOT NULL,
  상품번호   VARCHAR2(20) NOT NULL,
  수량       NUMBER,
  CONSTRAINT uk_주문상세 UNIQUE (주문번호, 상품번호)  -- 본질식별자를 지킨다
);

시험은 이 부작용 목록을 그대로 묻거나, 「인조식별자를 쓰면 중복이 생길 수 있다」는 문장의 참거짓을 묻습니다. 인조식별자 자체가 나쁜 것은 아니고 본질식별자가 지키던 규칙을 대신 지켜 줄 장치를 안 두는 것이 문제라는 쪽으로 이해해 두면 어느 형태로 나와도 풀립니다.

연습 문제

  1. 주식별자의 특징에 해당하지 않는 것은?
    ① 유일성
    ② 최소성
    ③ 불변성
    ④ 가변성
    ④. 주식별자는 값이 바뀌지 않아야 하므로 불변성이 특징이고 가변성은 그 반대입니다. 나머지 하나는 존재성입니다.
  2. 다음 중 주식별자로 쓰기에 가장 부적절한 속성은?
    ① 사원번호
    ② 주문번호
    ③ 사원의 이메일 주소
    ④ 계좌번호
    ③. 유일할 수는 있지만 바뀔 수 있어 불변성을 어깁니다. 값이 바뀌면 그 값을 외래키로 들고 있는 모든 테이블을 함께 고쳐야 합니다.
  3. 식별관계와 비식별관계에 대한 설명으로 옳은 것은?
    ① 식별관계에서 부모의 식별자는 자식의 일반 속성이 된다
    ② 비식별관계에서 자식은 부모 없이 존재할 수 없다
    ③ 식별관계는 ERD에서 실선으로, 비식별관계는 점선으로 그린다
    ④ 비식별관계로만 모델을 구성하면 주식별자가 계속 길어진다
    ③. ①은 비식별관계의 설명이고, ②는 식별관계의 설명입니다. ④는 반대로 식별관계로만 구성했을 때 생기는 문제입니다.
  4. 인조식별자를 도입했을 때 생기는 부작용으로 옳지 않은 것은?
    ① 본질식별자에 걸려 있던 유일성이 풀려 중복이 생길 수 있다
    ② 불필요한 인덱스가 늘어날 수 있다
    ③ 조인할 때 업무적으로 필요한 컬럼을 빠뜨릴 수 있다
    ④ 주식별자의 길이가 길어져 자식 테이블의 컬럼이 늘어난다
    ④. 인조식별자는 오히려 키를 짧게 만들려고 도입하는 것입니다. 키가 길어지는 문제는 식별관계를 계속 이어 갔을 때 생깁니다.
  5. 다음 테이블의 주식별자에 대한 설명으로 옳은 것은?
    「주문상세(주문번호, 상품번호, 수량) — 한 주문 안에서 같은 상품은 한 줄만 존재한다」
    ① 주문번호 하나로 식별되는 단일 식별자다
    ② 주문번호와 상품번호를 묶은 복합 식별자이자 본질식별자다
    ③ 수량을 포함해야 유일성이 만족된다
    ④ 상품번호는 보조식별자다
    ②. 한 주문 안에 같은 상품이 한 줄뿐이라는 업무 규칙이 두 컬럼의 조합을 유일하게 만듭니다. 주문번호만으로는 한 주문의 여러 상품이 구분되지 않고, 수량을 넣으면 최소성을 어깁니다.
  6. 보조식별자에 대한 설명으로 옳은 것은?
    ① 인스턴스를 구분할 수 있고 다른 엔터티와 관계도 맺을 수 있다
    ② 인스턴스를 구분할 수 있지만 대표성이 없어 관계를 맺지 못한다
    ③ 다른 엔터티에서 받아 온 식별자를 말한다
    ④ 두 개 이상의 속성으로 구성된 식별자를 말한다
    ②. 관계를 맺을 수 있는 것은 주식별자뿐입니다. ③은 외부식별자, ④는 복합 식별자의 설명입니다.
  7. 인조식별자를 쓰면서 본질식별자가 지키던 규칙을 함께 지키려면 무엇을 해야 하는가?
    ① 인조식별자 컬럼에 NOT NULL을 건다
    ② 본질식별자를 이루던 컬럼 조합에 유니크 제약을 건다
    ③ 본질식별자 컬럼들을 삭제한다
    ④ 인조식별자를 복합 식별자로 만든다
    ②. 인조키로 바꾸면 본질 컬럼 조합의 유일성이 풀리므로 유니크 제약을 따로 걸어 중복을 막습니다. ①은 인조키가 기본키면 이미 보장되는 것이고, ③은 업무 정보를 없애는 잘못된 선택입니다.

여기까지가 1과목 앞쪽 절반입니다. 다음 자리에서는 이 식별자와 속성을 재료 삼아 함수적 종속성과 정규화를 다룹니다. 식별자를 정확히 잡아 두지 않으면 정규화의 「무엇에 종속되는가」가 성립하지 않으므로, 네 가지 특징과 세 축의 분류는 여기서 끝내고 넘어가는 편이 좋습니다.

SQL 개발자(SQLD) 시험 노트 전체 보기