SQL Cook: 3. 8장 데카르트 곱 식별 및 방지하기

0

SQL_COOK

목록 보기
19/35
post-thumbnail

Q. 부서위치와 함께, 부서값이 10인 사원명을 반환하려고 한다

select e.ename, d.loc
	from emp e, dept d
    where e.deptno = 10
>>
ENAME	LOC
KING	NEW YORK
KING	DALLAS
KING	CHICAGO
KING	BOSTON
CLARK	NEW YORK
CLARK	DALLAS
CLARK	CHICAGO
CLARK	BOSTON
MILLER	NEW YORK
MILLER	DALLAS
MILLER	CHICAGO
MILLER	BOSTON

테이블 'EMP'의 'DEPNO'에만 값을 주다 보니 'DEPT' 테이블에서는 'DEPTNO'의 값에 상관없이 모든 열이 반환되었다

  1. 'EMP' 테이블과 'DEPT' 테이블을 alias e, d로 각각 불러왔다
  2. e의 'DEPTNO' 값이 10인 'ENAME'만 남기기로 한정했다
  3. d에는 아무런 조건이 없으므로 'LOC'의 모든 행이 반환된다
  4. 모든 경우의 수를 따져서 'ENAME'과 'LOC'가 조합된 결과셋이 반환된다

A. JOIN을 사용한다

부서값이 10인 사원명이 어디서 근무하는지가 특정되어야 한다.
'DEPTNO'열을 기준으로 두 테이블을 JOIN한다.

select e.ename, d.loc
	from emp e, dept d
    where e.deptno = d.deptno
    	and e.deptno = 10
>>
ENAME	LOC
KING	NEW YORK
CLARK	NEW YORK
MILLER	NEW YORK

반드시 JOIN 키워드를 사용해야하는 것은 아니다.

select e.ename, d.loc
	from emp e inner join dept d
    on e.deptno = d.deptno
    where e.deptno = 10
>>
ENAME	LOC
KING	NEW YORK
CLARK	NEW YORK
MILLER	NEW YORK

동일한 결과셋이 반환됨을 볼 수 있다.


카디널리티(Cardinality)

출처: 데이터 엔지니어님

정의

  • 특정 데이터 집합에서 유니크한 값의 개수를 의미한다

예시 쿼리

select count(distinct(deptno)) as cnt_of_deptno from emp;
>>
+----------------------+
| cnt_of_unique_deptno |
+----------------------+
|                    3 |
+----------------------+

유니크한 값의 개수는 3개다.
카디널리티는 3이다.

select count(deptno), deptno from emp  group by deptno;
>>
+---------------+--------+
| count(deptno) | deptno |
+---------------+--------+
|             4 |     10 |
|             5 |     20 |
|             6 |     30 |
+---------------+--------+

세 종류만 있다는 것도 확인할 수 있다.


예시 쿼리에서 잘못 반환되었던 행 수는 FROM절에 있는 두 테이블의 카디널리티 곱이다.
이 수치를 데카르트 곱이라고 한다.

이를 피하기 위해 일반적으로 'n-1' 규칙을 적용한다.
n은 FROM절의 테이블 수를 의미하며, 'n-1'은 필요한 최소한의 JOIN수다.


정리

  • 카디널리티란 유니크한 자료의 개수를 의미한다
  • 각 테이블의 카디널리티를 곱하면 모든 자료의 조합의 개수를 알 수 있다
  • 이를 데카르트 곱이라 부르며 일반적으로 올바른 반환 형태는 아니다
  • 데카르트 곱을 피하기 위해 'n-1'개의 JOIN사용이 권장된다

1개의 댓글

comment-user-thumbnail
2022년 7월 15일

새벽까지 열심히 공부하시는 모습 정말 멋져요!!

답글 달기