DB/SQL 전문가 가이드

[과목 I 2장 2절] 관계와 조인의 이해

꾸준함. 2025. 3. 17. 18:51

1. 조인

  • 아래 모델은 고객과 주문 엔티티가 관계를 맺고 있는 모습
    • 고객 엔티티의 입장에서는 `한 명의 고객은 여러 번 주문할 수 있음`
    • 주문 엔티티 입장에서는 `각각의 주문은 반드시 한 명의 고객에 의해 발생됨`
    • 관계를 맺음으로써 생기는 현상은 고객 엔티티의 식별자인 고객번호를 주문 엔티티에 상속시킨 것
    • 즉, 관계를 맺는다는 것은 식별자를 상속시키고 해당 식별자를 매핑 키로 활용해 데이터를 결합하여 보겠다는 것

 

https://highllight.tistory.com/71

고객번호 고객명
100 정우진
101 한형식
102 황영은

 

주문번호 고객번호 주문상태코드
1100001 100 주문완료
1100002 101 주문완료
1100003 101 취소요청
1100004 102 환불요청
1100005 100 교환완료

 

  • 주문 데이터의 [고객] 데이터에서 고객번호를 상속시킨 것을 볼 수 있음
  • 주문번호가 1100001인 주문의 고객명이 `정우진` 고객이라는 것을 어떻게 알 수 있을까?
    • 주문 데이터에서 주문번호가 1100001인 데이터를 조회
    • 주문번호가 1100001 데이터의 행에서 고객번호가 100 임을 확인 (JOIN)
    • 고객 데이터에서 고객번호가 100인 데이터를 조회 (JOIN)
    • 고객번호가 100인 데이터의 행에서 고객명이 `정우진`이라는 것을 확인

 

  • 고객번호가 조인키 (Join Key)

 

 

2. 계층형 데이터 모델

  • 아래 모델은 Sample Schema로 제공되는 EMP (사원) 모델
  • EMP 모델은 계층형 데이터 모델 (Hierarchical Data Model)이며 계층형 데이터 모델은 계층 구조를 가진 데이터를 지칭하는 것

 

https://highllight.tistory.com/71

 

https://highllight.tistory.com/71

 

  • [표 I-2-6]에서 주목해야 할 속성은 MGR 속성
    • MGR 속성은 각 사원 관리자의 사원번호를 의미
    • 즉 `SMITH` 관리자는 사원번호가 7902인 `FORD`가 됨
    • `FORD`의 관리자는 사원번호가 7566인 `JONES`
    • 이처럼 관리자를 찾는 과정은 앞서 언급한 JOIN이며 SQL로 표현하면 다음과 같음


 

  • 1번에서 언급한 사례와 다른 점은 자기 자신을 조인했다는 것이며 이를 셀프 조인 (Self-Join)이라고 지칭
  • 셀프 조인이 가능한 이유는 자기 자신에서 관계를 맺었기 때문
    • 관계를 맺으면 식별자를 상속한다고 하는데 아래 모델에서는 상속된 식별자가 바로 MGR 속성
    • 속성명만 다를 뿐 MGR 속성에는 EMPNO가 들어가기 때문에 매핑키로 활용하여 조인할 수 있음

 

https://highllight.tistory.com/71

 

3. 상호배타적 관계

  • 아래 모델은 개인, 법인고객이 존재하는 모델에서 주문과의 상호배타적 관계를 표현
    • IE 표기법에서는 상호배타적 관계 표기를 지원하지 않아 괄호화 유사한 선을 직접 그려줌
    • 해당 모델에서는 관계의 배타적관계로써 주문 엔티티에는 개인 또는 법인번호 둘 중 하나만 상속될 수 있음을 의미
    • 즉, 주문은 개인고객이거나 법인 고객 둘 중 하나의 고객만이 가능

 

https://highllight.tistory.com/71

 

주문번호 고객구분코드 개인/법인번호
1100001 01 1234
1100002 02 1122334455
1100003 01 1356
1100004 01 2556
1100005 02 2233445566

 

 

  • 주문 데이터를 보면, 개인/법인번호는 개인고객 또는 법인고객의 식별자가 상속된 값
    • 이때 고객구분코드의 값을 통해 개인고객의 식별자가 상속되었는지, 법인고객의 식별자가 상속되었는지를 나타냄 

 

  • 주문번호가 1100001인 주문의 주문자명을 보여주고 싶을 때는 SQL을 다음과 같이 작성하면 됨
    • 고객구분코드를 알 수 있다면 명확하게 개인고객 또는 법인고객 테이블을 선택하여 하나의 테이블만 조인하여 SQL을 작성할 수 있지만 그렇지 않은 경우 아래와 같은 SQL이 최선
    • 주의할 점은 개인번호와 법인번호에 중복이 발생되어서는 안 된다는 것
      • 법인번호는 10자리이므로 개인번호가 십억 명을 초과하지 않는다면 문제가 되지 않겠지만, 만일 그 이상이 될 경우 두 건의 데이터가 출력될 수 있음
      • 이에 해당할 경우 반드시 고객구분코드 값을 변수로 받아야 함


 

  • 만약 개인번호와 법인번호가 중복되지 않는다는 전제가 있다면 다음과 같은 SQL도 가능
    • 개인번호와 법인번호는 중복되지 않기 때문에 OUTER JOIN으로 연결
    • 둘 중 하나는 조인에 성공하기 때문에 아래와 같이 SQL을 작성해도 무방
    • 단, SELECT 절에서는 조인되는 테이블의 고객명을 가져와야 하기에 COALESCE 함수를 사용
    • 앞서 UNION ALL을 사용한 첫 번째 SQL의 경우 조인되는 결과가 없을 경우 공집합을 출력할 것이지만 OUTER JOIN을 활용한 해당 SQL은 조인되는 결과가 없을 때 한 건의 NULL ROWS를 출력하게 됨


 

참고

SQL 전문가 가이드 2020 개정판 - 한국데이터산업진흥원

반응형