josolha
다대다(M:N) 본문
DB 모델링 과정에서 다대다 관계가 나올 수 있다.
하지만 관계형 DB는 정규화된 테이블 두 개로 다대다 관계를 표현할 수 없다.
그러므로 연결 테이블을 추가해서 일대다 - 다대일 관계로 풀어내야 한다.
이유는 뭘까? 왜 안되는 걸까
그 이유는 관계형 데이터베이스가 테이블 간의 관계를 나타내는 데 있어서 '행(row)'과 '열(column)'의 구조를 사용하기 때문이다.
이 구조에서 각 행은 고유한 식별자(Primary Key)를 가지며, 다른 테이블의 행과는 외래 키(Foreign Key)를 통해 연결된다.
다대다 관계를 직접적으로 표현하려면, 한 행이 여러 행을 참조하고 동시에 여러 행에 의해 참조되어야 하는데,
이는 관계형 데이터베이스의 기본 구조와 맞지 않는다. 라고 한다....
구체적인 문제점
학생과 과목의 관계로 구체적인 예시를 보자.
우선 학생은 학번(PK),이름,학과에 대한 정보를 갖는다.
학과는 과목코드(PK),과목명,담당교수를 갖는다.
다대다가 가능하게 되면 문제점을 보자.
만약 홍길동이 S1, S2를 수강하고 장길산은 S2와 S3를 수강했다고 생각을 해보자
학생 테이블에서 학생의 수강 정보를 확인하기 위해서는 학생이 수강한 과목에 대한 정보가 필요하다.
또한 과목의 입장에서 과목의 수강생 정보를 관리하기 위해서는 수강 학생의 학번 정보가 유지 되어야 한다.
그럼 테이블은 아래와 같이 구성된다.
위와같이 구성된 다대다 관계에는 어떤 문제가 있을까?
- 각 테이블에서 기본 키(PK)로 단독으로 기능할 수 있는 컬럼이 없다.
- 예를 들어, 학생 테이블에서 학번만으로는 각 학생의 고유 데이터를 식별할 수 없게 되며,
과목 테이블에서도 과목 코드만으로는 고유한 과목 데이터를 식별할 수 없다.
('1번 학생이 수강하는 S1 과목'과 '1번 학생이 수강하는 S2 과목'을 구분할 수 없게 되는 것이다.)
- 예를 들어, 학생 테이블에서 학번만으로는 각 학생의 고유 데이터를 식별할 수 없게 되며,
- 학생 테이블에는 과목 코드가, 과목 테이블에는 학생의 학번이 중복되어 저장된다.
- 학생에서도 가능하고 과목에서도 가능해져서 애매한 상황이 발생한다.
- 학생이나 과목 중 하나의 정보가 변경될 때, 관련된 모든 데이터를 일관되게 유지하기 어렵다.
- 만약 홍길동이 전과를 해서 수학과로 학과를 변경해야 한다면 어떻게 될까?
학생 테이블에서 현재는 2군데의 데이터를 수정해야 한다. 여러 과목을 수강했다면 더욱 많은 데이터를 수정해야 한다
- 만약 홍길동이 전과를 해서 수학과로 학과를 변경해야 한다면 어떻게 될까?
해결방법
이러한 문제들 때문에 관계형 데이터베이스에서는 다대다 관계를 직접적으로 표현하기보다는 연결(중간) 테이블을 이용하여 이를 일대다, 다대일 관계로 분해하는 것이 일반적이다.이 방식은 데이터 무결성을 유지하고 쿼리의 복잡성을 줄이는 데 도움이 된다.
연결 테이블 도입에 의한 해결
- 각 수강 정보는 수강 ID를 통해 고유하게 식별된다.
- '학번 1' 학생이 'S1' 과 'S2' 과목을 수강하는 경우, 이 두 수강 정보는 서로 다른 수강 ID를 갖게 된다.
- 학생 정보와 과목 정보는 각각 학생 테이블과 과목 테이블에 한 번만 저장되며,
수강 테이블은 이들 사이의 관계만을 나타낸다. 이로 인해 데이터 중복이 방지된다. - 학생이나 과목의 정보가 변경되더라도, 연결 테이블은 영향을 받지 않으며, 데이터 무결성이 유지된다.