관계(Relationship)와 조인(Join)의 이해

2023. 3. 4. 23:53SQL/SQL 전문가 가이드(2020 개정판)

관계(Relationship)는 사전적으로 정의하면 '상호 연관성이 있는 상태'이며, 조인(Join)은 식별자를 상속하고, 상속된 속성을 매핑키로 활용하여 데이터를 결합하는 것을 의미합니다.

 

1. 조인

고객과 주문 엔터티가 관계를 맺고 있는 모습입니다. 고객 엔터티 입장에서는 '한 명의 고객은 여러 번 주문할 수 있다', 주문 엔터티 입장에서는 '각각의 주문은 반드시 한 명의 고객에 의해 발생된다' 정도로 이해할 수 있습니다.

 

[고객]

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

[주문]

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

 

1. 주문 데이터에서 주문번호가 1100001인 데이터를 찾습니다.

2. 주문번호가 1100001 데이터의 행에서 고객번호가 100 임을 확인합니다.

3. 고객 데이터에서 고객번호가 100인 데이터를 찾습니다.

4. 고객번호가 100인 데이터의 행에서 고객명인 '정우진'이라는 것을 확인합니다.

 

2번과 3번이 조인이고, 고객번호가 조인키(Join Key)입니다. 이를 SQL로 작성하면 다음과 같을 것입니다.

SELECT B.고객명	# 4번
  FROM 주문 A, 고객 B	
 WHERE A. 주문번호 = '1100001'	# 1번
    AND A. 고객번호 = B.고객번호	# 2, 3번

2. 계층형 데이터 모델

Sample Schema로 제공되는 EMP(사원) 모델입니다. 계층형 데이터 모델은 계층 구조를 가진 데이터를 지칭하는 것입니다. 

MGR 속성은 각 사원 관리자의 사원번호를 의미합니다. 

SELECT B.ENAME	# 4
  FROM EMP A, EMP B
 WHERE A.ENAME = 'SMITH'	# 1
 	AND A.MGR = B.EMPNO	# 2, 3

1. EMP A에서 ENAME가 'SMITH'인 데이터를 찾습니다.

2. EMP A에서 ENAME가 'SMITH' 데이터의 행에서 MGR이 7902라는 것을 확인합니다.

3. EMP B에서 EMPNO가 7902인 데이터를 찾습니다.

4. EMP B에서 EMPNO가 7902인 데이터의 행에서 ENAME가 'FORD'라는 것을 확인합니다.

 

셀프조인(self-Join)은 자기 자신을 조인했다는 것입니다. MGR 속성에는 EMPNO가 들어가며, 매핑키로 활용하여 조인할 수 있습니다. 계층형 데이터 모델은 데이터 간의 계층이 존재할 때 발생하는 모델이라 할 수 있습니다.

계층형 데이터 모델은 특수한 경우에만 발생하는 희귀한 모델은 아니며, 업무에 따라 충분히 만날 수 있는 모델이기에 개념을 명확하게 알고 있어야 합니다.

3. 상호배타적 관계

IE 표기법에서는 상호배타적 관계 표기를 지원하지 않아 괄호와 유사한 선을 직접 그려줍니다. 본 모델에서 관계의 배타적 관계로서 주문 엔터티에는 개인 또는 법인번호 둘 중 하나만 상속될 수 있음을 의미합니다.

 

주문

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

주문 데이터를 보면, 개인/법인번호는 개인고객 또는 법인고객의 식별자가 상속된 값입니다. 주문번호가 1100001인 주문의 주문자명을 보여주고 싶을 때는 SQL을 다음과 같이 작성해야 합니다.

SELECT B.개인고객명
  FROM 주문 A, 개인고객 B
WHERE A.주문번호 = 1100001
   AND A.고객구분코드 = 1100001
   AND A.개인/법인번호 = B.개인번호
UNION ALL
SELECT B.법인명
  FROM 주문 A, 법인고객 B
WHERE A. 주문번호 = 1100001
  AND A.고객구분코드 = '02'
  AND A.개인/법인번호 = B.법인번호

고객구분코드를 알 수 있다면 명확하게 개인고객 또는 법인고객 테이블에 선택하여 하나의 테이블만 조인하여 SQL을 작성할 수 있습니다. 개인번호와 법인번호가 중복되지 않는다는 전제가 있다면 다음과 같은 SQL도 가능합니다.

SELECT COALESCE(B.개인고객명, C.법인명) 고객명
  FROM 주문 A LEFT OUTER JOIN 개인고객 B
    ON (A.개인/법인번호 = B.개인번호) LEFT OUTER JOIN 법인고객 C
    ON (A.개인/법인번호 = C.법인번호)
WHERE A.주문번호 = 1100001;

개인번호와 법인번호는 중복되지 않기에 아우터 조인으로 연결했습니다. 아우터 조인을 활용한 두 번째 SQL은 조인되는 결과가 없다면 NULL값을 가진 한 건의 ROWS(NULL ROWS)를 출력하게 됩니다.

'SQL > SQL 전문가 가이드(2020 개정판)' 카테고리의 다른 글

Null 속성의 이해  (0) 2023.03.06
모델이 표현하는 트랜잭션의 이해  (0) 2023.03.05
정규화(Normalization)  (0) 2023.03.03
식별자(Identifier)  (0) 2023.03.02
관계(Relationship)  (0) 2023.03.01