관계형 데이터베이스에서 1:M 관계에 대해 알아보자.
1:M 관계는 부자지간 관계이다.
1:M
관계를 부자지간
으로 볼 수 있다. 가장 중요하고 근본적인 관계이다. 가장 흔하게 나타나는 일반적인 관계이기도 하다.
- 파일(트리) 구조도 1:M 관계이다.

❓만약 자식
과 손자
라는 테이블이 또 다시 1:M 관계를 맺는다고 했을 때, 부모
와 손자
간의 관계가 존재할까???
답은, NO 이다.
✅ 관계는 3개 테이블 간의 관계를 표현하지 않는다. 반드시 2개 테이블 간의 관계에만 관심이 있다.
PK & FK
- 부모 테이블의
PK
가 자식 테이블에서 표현되는 것을FK(foreign key)
라고 한다. - 자식 테이블의
FK
는 중복될 수 있지만 부모 테이블의PK
는 반드시 하나이다.
🚨 권고사항
PK 명칭과 FK 명칭은 일치하도록 사용하는 것이 좋다.
⭐️ 관계형 데이터베이스(RDB)는 부모 없는 자식을 막아준다.
부모 없는 자식을 막아준다는 것이 무슨 뜻일까?
RDBMS
는 부모 없는 자식의 관계를 허용하지 않는다. 따라서 다음과 같은 제약이 존재한다.
- 어떤 부모의
PK
가 자식 테이블의FK
로 사용될 때, 해당 부모의 데이터를DELETE
할 수 없다. 해당 부모를 삭제하면 해당 부모의PK
를FK
로 들고 있는 자식이 고아가 되기 때문이다. - 부모 없는 자식은
INSERT
할 수 없다. 즉,FK
가 걸려있는 테이블에 데이터를 삽입할 때는FK
를 반드시 설정해줘야지만INSERT
할 수 있다.
❓만약 부모 없는 자식 데이터가 생기면 무슨 일이 벌어질까.
부모 없는 자식 데이터는 가비지 데이터(Garbage Data)가 된다. outer join
으로 조회할 때 가비지 데이터가 드러나게 된다. 가비지 데이터가 생기면 COUNT
함수와 같은 집계 함수 결과에 치명적인 오차를 발생시킨다.
✅ 프로그래밍으로 가비지 데이터를 커버치는 행위는 쓰레기 코드를 만드는 것이다. 따라서, DB 스키마 설계 시 관계를 잘 설정해서 가비지 데이터가 생기지 않도록 하는 것이 매우 중요하다.
1:M 관계 PK, FK 설정 예제
학년
과 반
이라는 테이블들을 설계해보자. 학년
과 반
은 1:M
관계를 지닌다.
학년 테이블
학년 번호를 PK
로 설정했다.
열이름 | 데이터 타입 | NULL 허용 | |
---|---|---|---|
PK | 학년번호 | tinyint | x |
학년이름 | varchar(50) | o |
1 |
|
학년번호 | 학년이름 | |
---|---|---|
1 | 1 | 1학년 |
2 | 2 | 2학년 |
3 | 3 | 3학년 |
반 테이블
현재 PK
만 설정되어 있다.
💡 학년번호와 반번호를 함께 복합키로 설정한 이유는 학년별로 반 번호를 1반 부터 시작하도록 하기 위함이다. 만약, 반 테이블의 PK로 반 번호만을 설정하면 반 번호의 중복이 불가능하기 때문에 학년 별로 1반부터 시작하지 못한다. 이처럼 복합키를 이용하면 두 번째 필드(반 번호)의 중복을 허용할 수 있게 된다.
열이름 | 데이터 타입 | NULL 허용 | |
---|---|---|---|
PK | 학년번호 | tinyint | x |
PK | 반번호 | tinyint | x |
반이름 | varchar(50) | o |
1 |
|
두 번째 행(row) 데이터는 부모가 없다.
학년번호 | 반번호 | 반이름 | |
---|---|---|---|
1 | 1 | 1 | 1반 |
2 | 4 | 1 | 1반 |
외래 키 설정이 없기 때문에 부모 없는 자식 데이터(가비지 데이터)가 삽입되어 버렸다.
가비지 데이터를 우선 삭제해주자.
1 |
|
학년 테이블의 학년번호
를 반 테이블의 학년번호의 외래키
로 설정해준다.
열이름 | 데이터 타입 | NULL 허용 | |
---|---|---|---|
PK, FK | 학년번호 | tinyint | x |
PK | 반번호 | tinyint | x |
반이름 | varchar(50) | o |
다시 INSERT 구문을 실행해보면
1 |
|
✅ FOREIGN KEY 제약 조건에 위배되는 데이터는 INSERT 되지 않는다. 즉, FK가 설정된 테이블은 해당 FK 값이 부모 테이블의 PK 값으로 존재하는지 먼저 탐색한다. 그러고나서 부모(PK)가 정상적으로 있는 경우에만 INSERT가 수행된다.
학년번호 | 반번호 | 반이름 | |
---|---|---|---|
1 | 1 | 1 | 1반 |
2 | 3 | 1 | 1반 |
학년과 반 테이블을 조인하여 한 번에 조회해보자.
1 |
|
학년번호 | 학년이름 | 학년번호 | 반번호 | 반이름 | |
---|---|---|---|---|---|
1 | 1 | 1학년 | 1 | 1 | 1반 |
2 | 3 | 3학년 | 3 | 1 | 1반 |
요약 및 정리
- 1:M 관계는 부자지간 관계이다.
- PK & FK 설정이 제대로 되어 있다면 RDB는 부모 없는 자식 데이터 발생을 막아준다.
- PK 설정 전략에 따라 특정 필드의 중복을 허용할 수도 있고 방지할 수도 있다.