[Database] 13. Join

백하림's avatar
Feb 28, 2025
[Database] 13. Join

1. Join이란?

💡
두 개 이상의 테이블을 하나의 조회로 결합하여 데이터를 가져오는 방법. 테이블 간의 연관 관계를 잘 파악하는 것이 중요하며, 관계 유형은 다음과 같다.
  • 1:1 관계
  • 1:N 관계 (일대다 관계)
  • N:N 관계 (다대다 관계) → 행위 테이블(동사 역할)이 필요

2. Join 종류

💡

1) Inner Join

  • 두 테이블에서 조건이 일치하는 데이터만 조회
SELECT * FROM feed_tb ft INNER JOIN user_tb ut ON ft.user_id = ut.id;
notion image
💡

2) Outer Join

  • 한쪽 테이블의 모든 데이터를 출력하고, 일치하는 데이터가 없으면 NULL로 표시
  • Left Outer Join: 왼쪽 테이블의 모든 데이터를 포함
  • Right Outer Join: 오른쪽 테이블의 모든 데이터를 포함
SELECT * FROM feed_tb ft INNER JOIN user_tb ut ON ft.user_id = ut.id LEFT OUTER JOIN reply_tb rt ON ft.id = rt.feed_id;
notion image

3. 관계 설정 예시 (인스타그램 모델링)

💡

1) 유저와 피드 (1:N 관계)

  • 한 명의 유저는 여러 개의 피드를 작성할 수 있음
  • feed_tb 테이블에서 user_id를 외래 키로 참조
💡

2) 피드와 댓글 (1:N 관계)

  • 하나의 피드에는 여러 개의 댓글이 달릴 수 있음
  • reply_tb 테이블에서 feed_id를 외래 키로 참조
💡

3) 유저와 댓글 (1:N 관계)

  • 한 명의 유저는 여러 개의 댓글을 작성할 수 있음
  • reply_tb 테이블에서 user_id를 외래 키로 참조
notion image

4. 데이터 조회 예제

SELECT ft.title AS feed_title, ft.photo_url AS feed_picture, ut.username AS feed_writer, rt.content AS reply_content, rut.username AS reply_writer FROM feed_tb ft INNER JOIN user_tb ut ON ft.user_id = ut.id LEFT OUTER JOIN reply_tb rt ON ft.id = rt.feed_id LEFT OUTER JOIN user_tb rut ON rt.user_id = rut.id ORDER BY ft.id, rt.id;
notion image

5. Join을 사용하는 이유

💡
테이블을 분리하지 않고 모든 데이터를 한 테이블에 넣을 수도 있지만, 데이터 중복과 수정 비용 증가로 인해 비효율적일 수 있음.
요약하자면, 데이터의 무결성과 성능 최적화를 위해서 이다.

더미 데이터 세팅

CREATE TABLE user_tb( id int primary key auto_increment, username varchar(20), password varchar(20), email varchar(100) ); CREATE TABLE feed_tb( id int primary key auto_increment, title varchar(1000), photo_url varchar(100), user_id int ); CREATE TABLE reply_tb( id int primary key auto_increment, content varchar(100), user_id int, feed_id int ); insert into user_tb(username, password, email) values('ssar', '1234', 'ssar@nate.com'); insert into user_tb(username, password, email) values('cos', '1234', 'cos@nate.com'); insert into user_tb(username, password, email) values('love', '1234', 'love@nate.com'); insert into feed_tb(title, photo_url, user_id) values('계곡왔어요', 'http://xn--989a5b.com', 1); insert into feed_tb(title, photo_url, user_id) values('바다왔어요', 'http://xn--2j1b67o.com', 2); insert into reply_tb(content, user_id, feed_id) values('굿', 2, 1); insert into reply_tb(content, user_id, feed_id) values('별로', 3, 1); -- 1. 이너조인 select * from feed_tb ft inner join user_tb ut on ft.user_id = ut.id; select * from feed_tb; select * from user_tb; select * from emp; select * from dept; select * from emp e inner join dept d on e.deptno = d.deptno; -- 2. 이너조인 실패 사례 select * from reply_tb; select * from feed_tb ft inner join user_tb ut on ft.user_id = ut.id inner join reply_tb rt on ft.id = rt.feed_id; -- 3. 아우터 조인 (내가 원하는 테이블에 모든 데이터를 다 뽑으면서 조인하기 위해) select * from feed_tb ft inner join user_tb ut on ft.user_id = ut.id left outer join reply_tb rt on ft.id = rt.feed_id; -- 4. 화면 데이터 완성하기 (인라인뷰) select post.feed_title, post.feed_picture, post.feed_writer, post.reply_content, rut.username reply_writer from ( select ft.title feed_title, ft.photo_url feed_picture, ut.username feed_writer, rt.content reply_content, rt.user_id reply_writer_id from feed_tb ft inner join user_tb ut on ft.user_id = ut.id left outer join reply_tb rt on ft.id = rt.feed_id ) post left outer join user_tb rut on post.reply_writer_id = rut.id; -- 5. 화면 진짜 완성 select ft.title feed_title, ft.photo_url feed_picture, ut.username feed_writer, rt.content reply_content, rut.username reply_writer from feed_tb ft inner join user_tb ut on ft.user_id = ut.id left outer join reply_tb rt on ft.id = rt.feed_id left outer join user_tb rut on rt.user_id = rut.id;
Share article

harimmon