데이터베이스에서 함수 종속, 외래키 연결, 식별/비식별 관계에 대한 개념은 데이터베이스 설계와 관계형 데이터 모델에서 매우 중요한 주제들입니다. 각각에 대해 차례로 설명해 드리겠습니다.
함수 종속(Functional Dependency)은 데이터베이스에서 속성 간의 관계를 나타냅니다. 이는 어떤 속성(A)이 다른 속성(B)에 대해 유일하게 값을 결정할 수 있을 때를 말합니다. 일반적으로 함수 종속을 다음과 같이 표기합니다:
A → B
여기서, A는 결정자(determinant), B는 종속자(dependent)입니다. 즉, A가 B를 결정한다는 의미로, A 값이 같으면 B 값도 항상 동일해야 한다는 규칙을 따릅니다.
예시
학생 데이터베이스에서 학번이 학생의 이름을 결정할 수 있습니다.
학번 → 이름
이 의미는 특정 학번에 대해 하나의 이름만 있을 수 있다는 것입니다. 따라서 학번이 동일하면 이름도 동일해야 합니다.
외래키(Foreign Key)는 한 테이블의 필드가 다른 테이블의 기본 키(Primary Key)를 참조할 때 사용됩니다. 외래키는 테이블 간의 관계를 정의하며, 두 테이블 간의 참조 무결성(Referential Integrity)을 유지하는 데 중요합니다.
예시
학생과 수강 테이블이 있다고 가정해봅시다. 학생 테이블에는 학생번호가 기본 키이고, 수강 테이블에는 수강번호와 함께 학생번호가 있습니다. 여기서 수강 테이블의 학생번호는 학생 테이블의 학생번호를 참조하는 외래키입니다.
학생(학생번호, 이름)
수강(수강번호, 학생번호, 과목)
여기서 수강 테이블의 학생번호는 외래키로서 학생 테이블의 학생번호를 참조합니다.
테이블 간의 관계에서 식별(Identifying) 관계와 비식별(Non-Identifying) 관계는 외래키를 사용할 때 어떤 방식으로 관계를 설정하느냐에 따라 구분됩니다.
식별 관계는 자식 테이블의 외래키가 부모 테이블의 기본 키의 일부가 되는 관계를 말합니다. 즉, 자식 테이블의 기본 키는 부모 테이블의 기본 키에 의존하게 됩니다. 이때, 자식 테이블은 부모 테이블 없이 존재할 수 없습니다.
예시
가령 Order(주문)와 OrderItem(주문 항목) 테이블이 있을 때, 주문 항목은 주문과 반드시 연결되어야 하므로 OrderItem의 기본 키는 Order의 기본 키를 포함하게 됩니다.
CREATE TABLE Order (
order_id INT PRIMARY KEY
);
CREATE TABLE OrderItem (
order_id INT,
item_id INT,
PRIMARY KEY (order_id, item_id),
FOREIGN KEY (order_id) REFERENCES Order(order_id)
);
여기서 OrderItem의 기본 키는 (order_id, item_id)이고, order_id는 부모 테이블의 기본 키와 연결되어 있습니다. 이것이 식별 관계입니다.
비식별 관계는 자식 테이블의 외래키가 부모 테이블의 기본 키와는 별개로 자식 테이블의 고유한 기본 키를 가질 때 사용됩니다. 부모와 자식이 독립적인 기본 키를 가질 수 있으며, 부모 테이블의 존재 여부와 상관없이 자식 테이블의 레코드는 독립적으로 존재할 수 있습니다.
예시
Student와 Course 테이블이 있고, Enrollment(수강 신청) 테이블이 있다고 가정해봅시다. Enrollment는 학생과 강좌 간의 관계를 나타내지만, 학생과 강좌는 각각 독립적인 테이블입니다. 이 경우 Enrollment는 비식별 관계가 됩니다.
CREATE TABLE Student (
student_id INT PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE Course (
course_id INT PRIMARY KEY,
title VARCHAR(100)
);
CREATE TABLE Enrollment (
enrollment_id INT PRIMARY KEY,
student_id INT,
course_id INT,
FOREIGN KEY (student_id) REFERENCES Student(student_id),
FOREIGN KEY (course_id) REFERENCES Course(course_id)
);
여기서 Enrollment 테이블은 자체적으로 enrollment_id라는 기본 키를 가지며, 부모 테이블 Student와 Course의 외래키를 참조합니다. 이 관계는 부모 테이블의 기본 키가 자식 테이블의 기본 키에 포함되지 않기 때문에 비식별 관계라고 합니다.
Q1: 식별 관계와 비식별 관계 중 어느 상황에서 더 적합한지 판단하는 기준은 무엇인가요?
식별 관계와 비식별 관계는 데이터의 의존성에 따라 적절하게 선택됩니다. 주로 데이터 간의 강한 종속성이 필요한 경우에는 식별 관계를, 상대적으로 독립적인 데이터 관계를 표현할 때는 비식별 관계를 사용합니다.
강한 의존성: 자식 테이블이 부모 테이블 없이는 존재할 수 없는 경우입니다. 예를 들어, 주문(Order)과 주문 항목(OrderItem)의 관계에서, 주문 항목은 반드시 주문과 연결되어야만 의미가 있습니다. 주문 항목이 주문 없이 존재할 수 없다면, 식별 관계를 사용하여 자식 테이블의 기본 키에 부모 테이블의 키를 포함시킵니다.
복합 키가 자연스러운 경우: 자식 테이블에서 부모 테이블의 기본 키가 자식 테이블의 기본 키에 포함되어야 하는 경우, 식별 관계를 사용하는 것이 적합합니다.
따라서 데이터 간의 의존성이 매우 강하면 식별 관계를, 데이터가 독립적이거나 별도의 기본 키가 필요할 경우 비식별 관계를 사용합니다.
함수 종속성을 기반으로 테이블을 설계할 때는 정규화 과정을 통해 데이터 중복을 최소화하고, 데이터의 일관성을 유지할 수 있습니다. 정규화 과정은 여러 단계로 나뉘며, 각 단계에서 함수 종속성을 해결하는 방법이 달라집니다.
정규화 과정에서는 주로 함수 종속성을 분석하고, 각 테이블에 중복 데이터가 없는지, 불필요한 종속성이 없는지를 확인합니다. 정규화가 지나치면 성능이 저하될 수 있으므로, 정규화와 성능 사이의 균형을 맞추는 것이 중요합니다.
외래키는 데이터베이스에서 테이블 간의 관계를 설정하는 데 매우 중요하지만, 성능에 영향을 줄 수 있는 몇 가지 문제가 발생할 수 있습니다. 이를 해결하기 위한 몇 가지 방법은 다음과 같습니다.
정리하면, 인덱스 생성, 캐싱, 연쇄 작업 관리, 배치 처리 등의 방법을 통해 외래키로 인해 발생할 수 있는 성능 문제를 해결할 수 있습니다.