이번 포스팅은 데이터베이스의 JOIN
에 대한 내용을 담고 있습니다.
1987년 영국의 일러스트레이터 마틴 핸드포드가 그린 한 시대를 풍미한 그림책
윌리를 찾아라
를 혹시 기억하시나요?
동그란 안경
, 힌색과 빨간색의 스트라이프 긴팔티
, 청바지
, 모자
와 신발
까지,
모든것이 일치하는 하나의 캐릭터는 딱 한명, 윌리만 존재 합니다.
데이터베이스에서는 이렇게 조건에 일치하는 원하는 데이터를 얻기 위해 JOIN
연산을 사용합니다. 이번시간에는 JOIN
의 개념과 종류에 대하여 살펴 보겠습니다.
두개 이상의 테이블을 결합하여 데이터를 검색하는 방법
만일 얻고자 하는 데이터가 한개의 테이블
이 아니라 여러개의 테이블
에 나누어져 있다면
각 테이블의 컬럼을 한개씩 가져와서 그 컬럼을 접점으로 이용하여 여러 테이블에 나누어져 있는
데이터를 한번에 검색하게됩니다. 보통 접점으로 사용하는 컬럼은 PK
, FK
로 두 테이블을 연결합니다.
두 컬럼을 접점으로 비교하기 위해서 같은 데이터 타입을 사용하는 컬럼이어야 합니다.
그렇다면 굳이 왜 데이터를 한개의 테이블에 넣지 않고 두개의 테이블에 나누어서 넣은 후에
Join
이라는 과정을 거쳐서 데이터를 가져오는 걸까요?
아래의 테이블을 게시판의 DB테이블이라고 가정을 하고 생각해 보겠습니다. 이 경우에 만약
작성자의 나이가 어떠한 이유로 변경이 되었다면 테이블의 작성자 이름을 전부 수정해
주어야 할 것입니다.만약 게시글이 10만개라면 10만개를 모두 수정을 해줘야만 합니다.
하지만 아래처럼 게시판의 테이블과 회원의 테이블이 따로 분리되어 있다면 어떨까요?
게시판의 데이터양이 얼마가 되었던간에 회원테이블에서 한번만 이름을 변경해주면 끝납니다.
만약 게시판에서 게시글 작성자의 나이나 이름의 데이터가 필요하다면 작성자 아이디의 컬럼을 이용해서 JOIN을 해주면 얼마든지 나이와 이름의 데이터를 가져올 수 있습니다.
이러한 이유로 관계형데이터베이스에서 JOIN을 사용하고 있으며 JOIN에는 어떤 종류가 있는지 아래에서 한가지씩 살펴보도록 하겠습니다.
참고로 LEFT JOIN
과 INNER JOIN
이 두가지를 절대적으로 많이 사용하고 나머지는 사용빈도가 적은 편입니다.
첫번째로 살펴볼 JOIN
은 LEFT JOIN
입니다. 참고로 LEFT OUTER JOIN
을 줄여쓰면 LEFT JOIN
이 됩니다.
LEFT JOIN
말고도 RIGHT JOIN
도 있지만 사실상 LEFT JOIN과 방향만 다를 뿐 같은 개념이라고 생각하면 됩니다.
LEFT JOIN을 테스트 해보기 위해 아래의 테이블을 만들어 봤습니다.
위에서 만든 테이블 두개를 이용하여 LEFT JOIN을 아래의 쿼리문처럼 실행해 봤습니다.
SELECT * FROM BOARD A
LEFT JOIN ID B
ON A.ID_SEQ = B.ID_SEQ;
각 테이블의 id_seq컬럼을 이용하여 JOIN
을 했고 LEFT JOIN
이기 때문에 왼쪽에 위치한 ID테이블이 기준이 됩니다.
따라서 ID테이블에는 있지만 게시판테이블에는 없는 데이터의 경우 ID테이블의 정보는 그대로 출력되고 B테이블의 컬럼들에는 NULL값이 들어간채로 출력이 됩니다.
또는 다음과 같이 WHERE
절로 조건
을 주어 조회할 수 도 있습니다.
SELECT * FROM BBS A
LEFT JOIN ID B
ON A.ID_SEQ = B.ID_SEQ
WHERE B.ID_SEQ IS NULL
두번째로 살펴볼 JOIN은 INNER JOIN
입니다. 참고로 INNER JOIN
은 NULL
값이 없습니다.
JOIN
하는 두 테이블 모두에서 존재하는 값만 출력되기 때문입니다.
LEFT JOIN
에서 살펴봤던 예시의 테이블을 이용해서 INNER JOIN
을 하면 다음과 같습니다.
아래는 맨위쪽에있는 샘플테이블을 참고하여 만든 쿼리문과 쿼리문에 대한 결과값입니다.
SELECT * FROM BBS A
INNDER JOIN ID B
ON A.ID_SEQ = B.ID_SEQ
세번째로 살펴볼 JOIN
은 FULL OUTER JOIN
입니다.
참고로 FULL OUTER JOIN
을 지원하지 않는 DB가 많습니다. FULL OUTER JOIN
를 지원하지 않는 DB에서는 UNION
함수를 사용해서 FULL OUTER JOIN
을 대체하여 사용합니다.
아래는 맨위쪽에있는 샘플테이블을 참고하여 만든 쿼리문과 쿼리문에 대한 결과값입니다.
SELECT * FROM BOARD A
FULL OUTER JOIN ID B
ON A.ID_SEQ = B.ID_SEQ
UNION
SELECT * FROM BOARD A
UNION
SELECT * FROM ID B;
마지막으로 살펴볼 JOIN
은 EXCLUSIVE JOIN
입니다.
EXCLUSIVE JOIN
는 만약 테이블 두개를 JOIN
한다면 둘중 한가지 테이블에만 있는 데이터를 가져옵니다.
다른 JOIN
들과는 다르게 별도의 EXCLUSIVE JOIN
함수가 있는 것은 아니고 기존의 LEFT JOIN
과 Where
절의 조건을 함께 사용하여 만드는 JOIN
입니다.
아래는 맨위쪽에있는 샘플테이블을 참고하여 만든 쿼리문과 쿼리문에 대한 결과값입니다.
SELECT * FROM BOARD A
LEFT JOIN ID B
ON A.ID_SEQ = B.ID_SEQ
WHERE B.ID_SEQ IS NULL
이상으로 4가지의 Join
에 기본적인 사용법을 확인해 보았습니다.
JOIN
이 필요한 기본적인 이유는 앞서 포스팅한 정규화에서 출발합니다. 이상현상(Anomaly) 발생을 피하기위해 정규화를 통해 분할된 테이블을 생성했기 때문입니다.
테이블을 정규화하여 데이터를 분할하게 되면 정합성에 대한 문제를 해결할 수 있지만, 테이블간의 논리적인 연결관계가 필요하게 됩니다.
따라서 이러한 구체적인 논리관계를 표현하는 JOIN
을 잘못 기술하게 되면 시스템 자원 부족이나, 과다한 응답시간 지연을 발생시키는 원인이되므로, JOIN
조건은 신중하게 작성해야 합니다.
예시까지 있어서 이해하기 편했습니다! 좋은 글 감사합니다.