결합의 종류
기능적인 관점 -> 중점적으로 다룰 것
-크로스
-내부
-외부
그 외
-자기
-등가/비등가 : 등호(=)를 썼는가 안썼는가
-자연 : NATURAL JOIN 암묵적으로 같은 이름의 필드가 등호로 결합됨. (가독성, 확장성 떨어짐)
이중 크로스, 내부, 외부는 결과의 형태에 따라 구분되어 각각 배타적인 분류이다.
1. 크로스 결합
실무에서 사용할 기회는 거의 없다.
- 작동
Employees 테이블
사원 ID | 사원 이름 | 부서 ID |
1 | 하린 | 10 |
2 | 한미루 | 11 |
3 | 사라 | 11 |
4 | 중민 | 12 |
5 | 웅식 | 12 |
6 | 쿠와와 | 12 |
Department 테이블
부서 ID | 부서 이름 |
10 | 총무 |
11 | 인사 |
12 | 개발 |
13 | 영업 |
코드. 1
SELECT * FROM Employees CROSS JOIN Departments;
크로스 결합의 결과는 2개의 테이블의 레코드에서 가능한 모든 조합을 구해서 출력한다.
따라서 사원 테이블 1개에 대해 부서 테이블 4개가 결합되므로 6*4=24개의 레코드가 생성이 된다.
그렇다면 왜 실무에서 사용되지 않는가??
가능한 모든 경우의 수를 다 구하기 때문에 이러한 결과가 필요한 경우가 없다. 또한 결합의 비용이 매우 많이 드는 연산이다.
하지만 실수로 크로스 결합을 하는 경우는 꽤나 있다. 그 이유는 실수로 결합 조건을 적지 않을 때 발생한다.
코드. 2
SELECT * FROM Employees, Departments;
이를 예방하기 위해서 표준 SQL에 맞게 결합 구문을 사용하는 것이 좋다.
2. 내부결합
내부 결합은 가장 많이 사용되는 결합이다.
-작동
위에있는 테이블을 그대로 사용할 것.
결합을 사용할 때 결합 키는 양쪽 테이블 모두에 존재하는 부서 ID필드를 사용한다.
코드.3
SELECT E.emp_id, E.emp_name, E.dept_id, D,dept_name
FROM Employees E INNER JOIN Departments D
ON E.dept_id = D.dept_id;
emp_id | emp_name | dept_id | dept_name |
1 | 하린 | 10 | 총무 |
2 | 한미루 | 11 | 인사 |
3 | 사라 | 11 | 인사 |
4 | 중민 | 12 | 개발 |
5 | 웅식 | 12 | 개발 |
6 | 쿠와와 | 12 | 개발 |
내부 결합의 결과는 모두 크로스 결합 결과의 일부분이다. 이것이 내부 결합에서 내부라는 용어를 사용하는 이유이다.
내주 결합의 내부는 '데카르트 곱의 부분 집합'이라는 의미이다.
비용의 제한이 없다면 가장 쉽게 내부 결합을 구하는 알고리즘을 만든다면 크로스 결합으로 결과를 내고 결합 조건으로 필터링하는 것이다.
하지만 실제는 결합 대상을 최대한 축소하는 형태로 작동한다. 그 내용은 '결합 알고리즘과 성능'에서 설명하겠다.
- 내부 결합과 같은 기능을 하는 상관 서브쿼리
내부 결합은 기능적으로 상관 서브쿼리를 사용해 대체 가능한 경우가 많다. 위의 코드 3을 상관 서브쿼리로 작성해보겠다.
코드.3 (비교용 복붙)
SELECT E.emp_id, E.emp_name, E.dept_id, D,dept_name
FROM Employees E INNER JOIN Departments D
ON E.dept_id = D.dept_id;
코드. 4
SELECT E.emp_id, E.emp_name, E.dept_id,
(SELECT D.dept_name FROM Departments D
WHERE E.dept_id = D.dept_id) AS dept_name
FROM Employees E;
어렵게 느껴질 수 있지만 사원테이블에서 emp_id, emp_name, dept_id 3개의 필드를 선택한것 뿐이다.
중요한 부분은 부서 이름(dept_name_을 선택하는 줄이다. 상관 서브쿼리 내부에서 결합 조건을 기술하고 있는데, dept_id는 부서 테이블의 기본 키이브로, 이를 조건으로 지정하면 레코드가 한 개로 한정될 것이 보장이 된다. 따라서 기본 키를 사용하면 상관 서브쿼리를 스칼라 서브쿼리로 사용할 수 있다.
∴스칼라 서브쿼리 - 리턴값이 하나의 단일 값인 쿼리
기본적으로는 서브쿼리를 사용하는 것보단 결합을 사용하는 것이 좋다. (비용 절감 됨)
3. 외부 결합
외부는 '데카르트 곱의 부분 집합이 아니다'라는 의미다. 다만, 데이터 상태에 따라 경우에 따라서는 데카르트 곱의 부분 집합이 되기도 한다.
-외부 결합의 작동
외부 결합은 세 가지 종류가 있다.
-왼쪽 외부 결합
-오른쪽 외부 결합
-완전 외부 결합
왼쪽과 오른쪽은 실질적으로 같은 기능을 가진다. 마스터가 되는 테이블을 왼쪽에 적으면 왼쪽 외부 결합, 오른쪽에 적으면 오른쪽 외부 결합이다. 즉 결과는 동일하다. 쿼리를 보고 이해해 보자
코드 5.
-- 왼쪽 외부 결합
SELECT E.emp_id, E.emp_name, E.dept_id, D.dept_name
FROM Departments D LEFT OUTER JOIN Employees E
ON D.dept_id = E.dept_id;
-- 오른쪽 외부 결합
SELECT E.emp_id, E.emp_name, E.dept_id, D.dept_name
FROM Employees E RIGHT OUTER JOIN Departments D
ON D.dept_id = E.dept_id;
emp_id | emp_name | dept_id | dept_name |
1 | 하린 | 10 | 총무 |
2 | 한미루 | 11 | 인사 |
3 | 사라 | 11 | 인사 |
4 | 중민 | 12 | 개발 |
5 | 웅식 | 12 | 개발 |
6 | 쿠와와 | 12 | 개발 |
NULL | NULL | 13 | 영업 |
마지막을 보면 크로스 결합에서는 생성되지 않는 레코드가 생성되었다.
마스터 테이블 쪽에만 존재하는 키가 있을 때는 키를 제거하지 않고 결과에 보존한다. 따라서 키를 모두 가진 레이아웃의 리포트를 만들 때 자주 사용된다. 즉, 키를 모두 가진 레이아웃의 리포트를 만들 때 자주 사용한다.
(RDB에서 NULL이 생성되는 테이블이 나오는거 자체가 좋은건지는 모르겠다.)
4. 외부 결합과 내부 결합의 차이
5. 자기 결합
자기 결합은 자기 자신과 결합하는 연산이다. 즉, 연산의 대상으로 무엇을 하느냐에 따라 나눈 분류이다.
-작동
자기 결합을 위한 테이블
Digits
digit(숫자) |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
자기 결합 + 크로스 결합
SELECT D1.digit + ( D2.digit * 10 ) AS seq
FORM Digits D1 CROSS JOIN Digits D2;
결과는 레코드가 0~99 까지의 숫자로 된 100개의 레코드가 나온다. D1, D2 를 마치 다른 테이블인 것 같이 다룬다. 그렇기 때문에 논리 레벨에서 보면 서로 다른 두 개의 테이블이 결합한다고 봐도 상관없다.
'DB > 관계형 DB' 카테고리의 다른 글
서브쿼리 (0) | 2021.03.12 |
---|---|
조인(결합) 알고리즘과 성능 (0) | 2021.02.19 |
인덱스 정리 (종류, 고려해야 할 부분, 사용할 수 없는 경우, 대처) (0) | 2021.02.12 |
Select (0) | 2021.01.22 |
도메인 설계 전략 (0) | 2021.01.19 |