Join 이란?

조인(Join)이란 하나의 테이블이 아닌 두 개 이상의 테이블을 묶어서 하나의 결과물을 만드는
것을 얘기한다. MySQL에서는 JOIN이라는 쿼리로, MongoDB에서는 lookup이라는 쿼리로 이를 처리한다.

참고로 RDBMS보다 DBMS가 조인연산에 대해 성능이 떨어진다고 벤치마크 테스트에서 알려져 있다.
즉, MongoDB에서는 되도록 lookup을 사용하지 말아야한다. 여러 테이블을 조인하는 작업이 많을 경우
에는 관계형 데이터베이스를 사용하는게 적합하다.


Join의 종류

image
그림 출처 - 소찾나님

Join의 종류는 위와 같다.

가장 대표적으로 많이 사용하는 조인은 3가지가 있다. (위에 그림에서 상위 3개)

  • LEFT OUTER JOIN : 왼쪽 테이블의 모든 행이 결과 테이블에 표기된다.
  • INNER JOIN : 왼쪽 테이블과 오른쪽 테이블의 두 행이 모두 일치하는 행이 있는 부분만 표기된다.
  • RIGHT OUTER JOIN : 오른쪽 테이블의 모든 행이 결과 테이블에 표기된다.


테이블을 실제로 만들어서 예제를 적용시켜 보자.
MYSQL을 기준으로 작성을 해본다.

image

Member 테이블에는 아래와 같은 정보를 삽입 하였고 (3개)

image


POSTS 테이블에는 아래와 같은 정보를 넣어 두었다. (4걔)

image



1. LEFT JOIN

image

LEFT JOIN은 LEFT OUTER JOIN과 동일한 말이다.
MEMBER를 A라고 기준을 두고 POST를 B라고 가정하고 SQL을 작성해보자

SELECT * 
FROM member m
LEFT JOIN posts p 
ON m.id = p.id;

image

실행결과는 위와 같이 나온다. member 테이블의 id와 posts id가 같은걸
LEFT JOIN을 실행하는 구문이다. member 테이블을 기준으로 조회하기 때문에
총 3개의 레코드가 표현되어진 것을 볼 수 있다.

반대로 posts 테이블을 A로 두고 SQL문을 작성한다면

image

위와 같이 posts 테이블을 기준으로 member를 가져오고
데이터가 없는 자리에는 null이라는 값으로 채워진다.


2. INNER JOIN

image

INNER JOIN의 특성은 교집합의 데이터만 가져온다는 것이다.

SELECT * 
FROM posts p
JOIN member m
ON m.id = p.id;

image

이번에는 posts를 A로 두고 INNER JOIN을 실행시켜 보았다.
LEFT JOIN에서는 값이 null로 들어왔지만, INNER JOIN에서는
같은 값만 가져오기 때문에 4번의 행을 가져오지 않은 모습을 볼 수 있다.


3. RIGHT JOIN

image

RIGHT JOIN은 사실상 LEFT JOIN의 반대 개념이기 떄문에 이해하기가 쉽다.

SELECT * 
FROM member m
RIGHT JOIN posts p
ON m.id = p.id;

image

member를 A로 두고 RIGHT JOIN을 시켰을때 위와 같이
4번째행의 데이터가 없기 때문에 null로 표현되고 posts의 데이터를
전부 가져온 모습을 볼 수 있다.


4. 합집합 JOIN (FULL JOIN)

image

FULL OUTER JOIN이라고도 부른다. MySQL에서는 해당 조인 기능을 지원하지 않는다.
대시 LEFT,RIGHT JOIN과 UNION을 이용해 FULL JOIN처럼 사용이 가능하다.
(UNION은 여러 테이블에 존재하는 같은 성격의 값을 한번의 쿼리로 출력하도록 돕는 연산자이다.)

SELECT * 
FROM member 
LEFT JOIN posts ON member.id = posts.id
UNION
SELECT * 
FROM member
RIGHT JOIN posts ON member.id = posts.id;

image

최종적으로 출력해보면 모든 테이블의 데이터를 가져오는 모습을 볼 수 있다.


5. 차집합 JOIN

image

차집합을 구하는 LEFT, RIGHT JOIN이 있다.
사실 LEFT, RIGHT JOIN의 개념만 알고 있으면 유추가 가능한
부분이므로 간단하게 설명하고 넘어가겠다.

SELECT * 
FROM posts p
LEFT JOIN member m
ON m.id = p.id WHERE m.id IS NULL;

image

현재 차집합을 테스트해보려면 수량이 많은 posts 테이블을 A로 두어야했다.
따라서 member 테이블을 B로 두었다.
LEFT JOIN에서 추가된 코드는 m.id IS NULL만 추가되었다.
member 테이블의 id가 null인 값들만 가져오게하는 구문이다.
말은 즉슨, A만 가지고 있는 값만 표시하겠다라는 의미와 동일하고 그래서 출력이 4번만 나온 것이다.


JOIN 원리

1. 중첩 루프 조인

Nested Loop Join이라고 부르며
중첩 루프 조인은 중첩 for문과 같은 원리로 조건에 맞는 조인을 하는 방법이다.
랜덤 접근에 대한 비용이 많이 증가하므로 대용량의 테이블에서는 사용하지 않는다.

JOIN을 할 때 먼저 액세스 되어 ACCESS PATH를 주도하는 테이블을 Driving Table이라고 하고
나중에 엑세스 되는 테이블을 Driven Table 이라고 한다.

 for(i=0; i<dept.length; i++) { -- driving table 
    for(j=0; j<emp.length; j++) { -- driven table
       // Search
    } 
}


2. 정렬 병합 조인

Sort Merge Join이라고 부르며
조회의 범위가 많을 때 주로 사용하는 조인 방법론이다.
양쪽 테이블을 각각 Access 하여 그 결과를 정렬하고 그 정렬한 결과를 차례로
Scan 해 나가면서 연결고리의 조건으로 Merge를 하는 방식이다. 주로 칼럼에 인덱스 없거나
출력해야할 결과 값이 많을 때 사용한다. 중첩 루프 조인의 조인 방식과 장단점이 서로 바뀌었다고
생각하면 이해하기가 쉽다.


3. 해쉬 조인

Hash Join은 두 테이블 중 하나를 해시 테이블로 선정하여 조인될 테이블의
조인 키 값을 해시 알고리즘으로 비교하여 매치되는 결과값을 얻는 방식입니다.
주로 많은 양의 데이터를 조인해야 하는 경우 주로 사용하고
JOIN 칼럼에 인덱스가 없어 중첩 루프 조인이 비효율적일 떄 사용한다.