이 노트는 정규화 분해를 두 질문으로 나누어 읽습니다. 분해된 테이블을 다시 조인했을 때 원래 튜플을 정확히 복원하는지와, 부분 테이블의 제약만으로 원래 함수 종속을 계속 집행할 수 있는지는 서로 다른 판정이며, 실제 동시 쓰기에서는 세 번째로 집행 경계까지 확인해야 합니다.
분해·재조인과 가짜 행 생성
R(A,B,C)에 (a1,b1,c1), (a2,b1,c2)가 있고 A→B만 제약이라고 합시다. AB와 BC로 나누면 두 테이블의 공통 B=b1 때문에 조인에서 원래 없던 (a1,b1,c2), (a2,b1,c1)가 생깁니다. 샘플에서 조인이 성공했다는 말보다 모든 유효 관계에서 원래 튜플만 복원되는지를 확인해야 합니다.
무손실 조인은 분해 뒤 자연 조인으로 원래 관계를 정확히 복원하는 성질입니다. 종속성 보존은 각 분해 테이블의 제약만 검사해도 원래 함수 종속을 강제할 수 있는 성질입니다. 둘은 다릅니다.
함수 종속은 같은 결정자 값을 가진 튜플들의 결정 속성 값이 같아야 한다는 규칙입니다. 무손실성은 이 규칙을 만족하는 원본 관계 각각에 대해 검사해야 하며, 한 샘플의 조인이 그럴듯하다는 사실은 충분하지 않습니다. 종속성 보존은 이후 INSERT나 UPDATE를 검사할 때 어떤 테이블만 읽어도 되는지에 관한 별도 운영 조건입니다.
공통 속성 폐포에 의한 이항 분해 검사
R을 두 테이블 R1과 R2로 나눌 때 둘이 함께 갖는 열 X=R1∩R2가 한쪽 테이블의 나머지 열을 결정하면, 두 테이블을 같은 공통 열 값으로 붙이는 자연 조인에서도 가짜 행을 만들지 않는 이항 무손실 분해로 볼 수 있습니다. 실제 계산에서는 X에 함수 종속을 반복 적용한 폐포 X+가 R1 또는 R2의 모든 속성을 포함하는지 확인합니다. 예를 들어 AB·AC 분해에서는 공통 A의 폐포 A+={A,B}가 AB 전체를 결정하지만, AB·BC에서는 B+={B}라 어느 쪽도 결정하지 못합니다. 이 판정은 함수 종속을 따르는 관계 모델의 조건이며 SQL NULL, bag 중복, 제약 미집행은 자동으로 포함하지 않으므로 실제 DB 동작은 따로 확인해야 합니다.
| 분해 | 공통 속성 | F={A→B}의 폐포 | 판정 |
|---|---|---|---|
| AB, AC | A | A+={A,B} | AB 결정, 무손실 |
| AB, BC | B | B+={B} | 어느 쪽도 결정 못함, 무손실 보장 없음 |
AB·AC에서 A가 각 B를 고정하므로 AC의 각 A,C에 붙는 B가 하나입니다. AB·BC에서는 같은 B를 가진 A와 C의 원래 연결 정보가 사라질 수 있습니다. 다중 분해는 단계별 이항 분해 증명이나 chase 같은 표준 절차로 확인하고 이 조건을 아무 다중 분해에 단순 적용하지 않습니다.
계산 절차는 먼저 공통 속성 X를 쓰고, X+에 함수 종속의 왼쪽이 포함될 때마다 오른쪽 속성을 반복해서 추가하는 것입니다. AB·AC에서 A+가 B를 얻으므로 한쪽 전체 AB를 결정하지만, AB·BC에서는 B+가 B에서 멈춰 어느 쪽 전체도 결정하지 못합니다. 이 추적은 “공통 열이 있다”와 “공통 열이 연결을 고정한다”를 구분하는 최소 검산입니다.
3NF 만족과 BCNF 위반의 공존
R(S,C,I)를 학생·과목·강사로 두고 SC→I, I→C를 가정합니다. 강사는 한 과목만 담당하고 학생은 한 과목에 한 강사에게 배정된다는 규칙입니다. 후보키는 SC와 SI이며 S·C·I 모두 prime attribute입니다.
I→C의 I는 학생을 결정하지 못해 superkey가 아닙니다. 따라서 BCNF는 위반하지만 오른쪽 C가 prime이므로 3NF는 허용할 수 있습니다. BCNF는 모든 비자명 X→Y의 결정자 X가 superkey여야 하는 더 강한 조건입니다.
그림을 글로 읽기
- R(학생 S, 과목 C, 강사 I): SC→I, I→C
- 강사과목 IC: I가 키
- 학생강사 SI: SI가 키
- R(학생 S, 과목 C, 강사 I) → 강사과목 IC: I→C 분리
- R(학생 S, 과목 C, 강사 I) → 학생강사 SI: 수강 배정 관계
IC·SI의 공통 I는 IC를 결정하므로 무손실입니다. 그러나 IC에서 I1→C1, I2→C1이 모두 유효하고 SI에 S1,I1과 S1,I2를 넣으면 각 테이블의 로컬 키는 만족해도 조인에서는 같은 S1,C1에 강사 둘이 생겨 SC→I를 위반합니다.
투영 종속과 원래 제약의 유도 가능성
각 부분 관계에 투영한 함수 종속의 합에서 원래 SC→I를 유도할 수 없다면 종속성이 보존되지 않은 것입니다. BCNF 분해가 무손실이라는 증명은 이런 새 부분 관계 상태의 제약 위반을 자동 막지 않습니다.
따라서 제약 집행 비용이 중요하면 종속성 보존 3NF 설계를 유지하는 선택도 합리적입니다. 더 강한 중복 제거가 항상 실무 최적은 아닙니다. 조인·쓰기·검증 비용과 핵심 제약의 표현력을 함께 봅니다.
실무 선택에서는 BCNF의 중복 감소보다 자주 검사되는 제약의 집행 비용을 먼저 비교합니다. 분해 후에도 각 쓰기 경로가 여러 테이블을 조인해야만 SC→I를 확인할 수 있다면, 애플리케이션 검증·잠금·serializable 재시도가 누락될 때 정규화 이득이 제약 손실 비용으로 바뀝니다. 3NF 유지와 BCNF 분해 중 어느 쪽이 맞는지는 무손실성만으로 결정하지 않습니다.
동시 삽입을 고려한 조인 검사
A가 S1에게 I1을, B가 S1에게 I2를 동시에 배정하면 두 거래가 각각 “아직 충돌하는 배정이 없다”고 읽은 뒤 서로 다른 행을 삽입할 수 있고, 그 결과 같은 S1·C1에 강사 둘이 생겨 SC→I가 깨집니다. trigger 안에서 SELECT를 실행해도 두 조회 시점이 겹치면 같은 경쟁이 남으므로 적절한 격리·잠금이 필요합니다. 모든 경로가 학생별 권위 행을 잠근 뒤 확인·삽입하도록 직렬화하거나, serializable 충돌을 거래 전체로 재시도하거나, SC를 원자적으로 유일하게 만드는 모델을 선택할 수 있습니다. 빈 결과 자체에는 잠글 행이 없을 수 있어 FOR UPDATE만으로 범위를 보호한다고 볼 수 없고, I→C 변경도 기존 배정에 영향을 주므로 그 경로까지 같은 제약 체계에 넣어야 합니다.
유효 원본 복원과 무효 부분 상태 거절의 분리
유효한 R을 분해·재조인해 가짜 행이 없는지 확인하는 시험과, 위의 I1·I2 예처럼 로컬 제약만 만족하는 무효 상태를 삽입해 거절되는지 확인하는 시험을 나눕니다. 동시 삽입은 장벽으로 조회 시점을 맞추고 최종 SC→I가 유지되는지 검사합니다.
본문은 함수 종속 기반 관계 모형입니다. 실제 DB에서는 NULL·고유 제약·transaction·trigger의 제품 계약을 별도로 검증해야 하며 여기서 다중 세션 DB 실험을 수행한 것은 아닙니다.
두 검사는 서로 다른 실패를 겨냥합니다. 유효 R을 분해·재조인하는 시험은 가짜 튜플 생성을 찾고, 각 부분 테이블만 유효하지만 원래 제약은 깨지는 상태의 삽입 시험은 종속성 보존·집행 누락을 찾습니다. 동시 삽입 시험에서 기대 결과를 “한 거래가 실패하거나 재시도되어 최종 SC→I가 유지됨”으로 명시해야 단순히 두 요청이 2xx였다는 결과를 성공으로 오해하지 않습니다.