🧊 JOIN이란?
RDBMS는 데이터의 중복을 피하기 위해 데이터를 여러 단위로 쪼개서 여러 테이블로 나눠서 저장한다. 이렇게 분리되어 저장된 데이터에서 원하는 결과를 다시 도출하기 위해 여러 테이블을 조합할 필요가 있다.
서로 관계있는 데이터가 여러 테이블로 나뉘어 저장되므로 각 테이블에 저장된 데이터를 효과적으로 검색하기 위해 조인이 필요하게 된다.
🧊 JOIN의 종류
Join을 공부하기 전에 먼저 예시 테이블을 하나 만들어야 한다
1. Inner Join
- 여러 어플리케이션에서 사용되는 가장 흔한 결합 방식이며 기본 조인 형식으로 간주되었다.
- 내부 조인은 조인 구문에 기반한 2개의 테이블의 컬럼 값을 결합함으로써 새로운 결과 테이블을 생성한다.
JOIN SQL은 명시적 표현과 암묵적 표현법 2가지 구문으로 지정할 수 있다.
# 명시적 표현법
SELECT *
FROM employees
INNER JOIN dept_emp
ON employees.emp_no = dept_emp.emp_no;
# 암묵적 표현법
SELECT *
FROM employees, dept_emp
WHERE employees.emp_no = dept_emp.emp_no;
결과
이런식으로 교집합을 통해 가져오기 때문에 department_id 라는 컬럼이 중복되어서 테이블에 나타나는 것을 확인할 수 있다
Natural Join
- 동등 조인의 한 유형으로 동등조인은 조인 구문에서 동등한 비교만을 사용하는 것이다. 어쨋든 동일한 컬럼명을 가진 2개의 테이블에서 모든 컬럼들을 비교하면서 암시적으로 일어나는 구문이다.
- 결과적으로 나온 조인된 테이블은 동일한 이름을 가진 컬럼의 각 쌍에 대한 단 하나의 컬럼만을 포함하고 있다
SELECT * FROM employee NATURAL JOIN department;
결과
컬럼은 중복되지 않고 깔끔하게 가져오는 것을 볼수 있지만 natural은 문제가 많다. 동일한 이름의 컬럼이 여러개 존재할 경우 예상하지 못한 결과를 초래할 수 있고 명시적으로 조건을 제시하지 않기 때문에 결과를 예상하지 못하는 것은 똑같다 그래서 inner join , outer join을 사용하는 것을 권장한다.
2. Cross Join
- 조인되는 두 테이블에서 곱집합을 반환한다.
- 즉, 두번째 테이블로부터 각 행과 첫번째 테이블에서 각 행이 한번씩 결합된 열을 만들것이다.
- 예를 들어 m행을 가진 테이블과 n행을 가진 테이블이 교차조인이 되면 m*n개의 행을 생성한다
# 명시적 표현
SELECT * FROM CROSS JOIN department;
# 암시적 표현
SELECT * FROM employee, department;
결과
3. Outer Join
Outer Join은 크게 세가지로 나뉜다. LEFT, RIGHT, FULL 나눠보기 전에 그 자체의 의미를 알아보자면
조인 대상 테이블에서 특정 테이블의 데이터가 모두 필요한 상황에서 외부 조인을 활용해서 효과적으로 결과 집합을 생성할 수 있다.
Left Outer Join
- 우측 테이블에 조인할 컬럼의 값이 없는 경우 사용한다
- 즉, 좌측 테이블의 모든 데이터를 포함하는 결과 집합을 생성한다.
SELECT * FROM employee LEFT OUTER JOIN department ON employee.department_id = department.department_id;
결과
보이는 것처럼 왼쪽(employee)테이블에 데이터를 모두 가져오고 department에 중복되는 값은 넣어주고 아닌 값을 모두 null처리를 해주는 것으로 볼수 있다.
Right Outer Join
- 좌측 테이블에 조인할 컬럼의 값이 없는 경우 사용한다
- 즉, 우측 테이블의 모든 데이터를 포함하는 결과 집합을 생성한다.
SELECT * FROM employee RIGHT OUTER JOIN department ON employee.department_id = department.department_id;
결과
위의 쿼리문에서 변경된건 오로지 LEFT에서 RIGHT가 된 것이다. 하지만 이에 대한 결과는 다르다는 것을 알 수 있다. 오른쪽 테이블과 왼쪽 테이블의 데이터 모두를 가져오지만 오른쪽 테이블이 기준이 되기에 왼쪽과 오른쪽에 겹치는 데이터가 없어도 오른쪽 테이블의 데이터는 우선 전부 가져오는 것이다.
Full Outer Join
- 양쪽 테이블 모두 Outer Join이 필요할 때 사용한다
SELECT * FROM employee FULL OUTER JOIN department ON employee.department_id = department.department_id;
💥 하지만 현재 실습을 위해 사용하는 DB인 MySQL은 Full Outer를 지원하지 않는다. 그래서 다르게 설정해주어야 한다.
SELECT *
FROM employee
LEFT OUTER JOIN department
ON employee.department_id = department.department_id
UNION
SELECT *
FROM employee
RIGHT OUTER JOIN department
ON employee.department_id = department.department_id;
Union은 합한다는 것이다. 어쩃든 이것으로 내가 원하는 결과물을 보일 수 있는것이다.
결과
위에 쿼리를 보면 알겠지만 결국 full은 left 와 right를 합친것이라고 볼 수 있다.
🧊 JOIN의 주의 사항과 고려사항
주의사항
- SQL 문장의 의미를 제대로 파악해야한다
- SQL은 성능에 굉장히 큰 영향을 미친다. 어떤 질의를 수행할 것인지를 명확하게 정의하고 비효율을 제거하여 최적의 쿼리문을 작성해야한다
- 명확한 조인 조건 제공
- 위에서 Cross Join을 보면 데이터의 갯수가 엄청나게 증가하는 것을 볼 수 있다. 조인 조건이 명확하지 않다면 자칫 발생할 수있는 문제고 저렇게 많은 데이터를 가져오게 되면 과부하로 인한 문제가 발생할 수 있다
고려사항
- 조인의 대상의 집합을 최소화
- 집합을 최소화 할 방법이 있다면, 조건을 먼저 적용해서 관계를 맺을 집합을 최소화 한 후에 조인을 맺는 것이 효율적이다
- 효과적인 인덱스의 활용
- 인덱스를 활용하면 조인 연산의 비용을 극적으로 낮추는 방법이 된다.
'CS > 💾 DB' 카테고리의 다른 글
JOIN과 서브쿼리의 차이 (1) | 2024.07.21 |
---|---|
💾 파티셔닝과 샤딩 (0) | 2024.05.31 |
💾 동시성 문제를 해결하는 방법 (0) | 2024.04.27 |
💾 낙관적 락(Optimistic) 과 비관적 락(Pessimisitic) (1) | 2024.04.27 |
💾 MVCC, 트랜잭션 ( 5 ) (feat. MySQL과 PostgreSQL 비교) (1) | 2024.04.27 |