모든 데이터를 한 곳에 몰아넣지 않고, 회원 정보와 게시글 정보를 담을 테이블을 각각 분리하여 생성한다. 이때 두 테이블을 연결해 줄 '연결 고리(외래키, Foreign Key)'를 설정하는 것이 핵심이다.
-- 데이터베이스 생성 및 선택
CREATE DATABASE IF NOT EXISTS site1;
USE site1;
-- 1) 회원 테이블 생성 (부모 테이블)
CREATE TABLE member (
member_id INT AUTO_INCREMENT PRIMARY KEY, -- 고유 번호 (기본키)
author_name VARCHAR(50) NOT NULL, -- 작성자 이름
author_email VARCHAR(100) NOT NULL -- 작성자 이메일
);
-- 2) 게시글 테이블 생성 (자식 테이블)
CREATE TABLE article (
article_id INT AUTO_INCREMENT PRIMARY KEY, -- 게시글 고유 번호
title VARCHAR(200) NOT NULL, -- 제목
content TEXT NOT NULL, -- 내용
member_id INT, -- 작성자가 누구인지 기록할 연결 고리
-- 외래키 설정: 이 테이블의 member_id는 member 테이블의 member_id를 참조한다.
FOREIGN KEY (member_id) REFERENCES member(member_id)
);
이렇게 테이블을 분리해 두면, 회원의 이메일이 바뀌어도 member 테이블만 UPDATE 하면 되므로 데이터 관리가 훨씬 안전해진다.
조인을 테스트하기 위해 가상의 데이터를 집어넣는다.
-- 회원 데이터 3명 추가 (이초보는 아직 글을 쓰지 않은 회원으로 가정)
INSERT INTO member (author_name, author_email) VALUES
('김코딩', 'kim@test.com'),
('박해커', 'park@test.com'),
('이초보', 'lee@test.com');
-- 게시글 데이터 3개 추가 (1번 김코딩이 2개, 2번 박해커가 1개 작성)
INSERT INTO article (title, content, member_id) VALUES
('첫 번째 글', '내용1', 1),
('두 번째 글', '내용2', 1),
('세 번째 글', '내용3', 2);
이제 클라이언트(웹 브라우저) 화면에 "글 제목과 작성자 이름"을 함께 보여주어야 한다. 서로 다른 테이블에 있는 정보를 하나로 합쳐서 조회할 때 JOIN을 사용한다.
글이 작성된 게시물과 그 글을 쓴 회원 정보가 모두 존재하는 데이터만 딱 맞춰서 가져온다.
-- article 테이블(a)과 member 테이블(m)을 합친다.
SELECT
a.article_id AS '글번호',
a.title AS '제목',
m.author_name AS '작성자'
FROM article AS a
INNER JOIN member AS m
ON a.member_id = m.member_id; -- 두 테이블의 member_id가 같은 것끼리 연결해라!
[실행 결과]
글을 한 번도 쓰지 않은 '이초보'의 정보는 출력되지 않는다. 양쪽 테이블에 모두 연결 고리가 있는 데이터만 교집합처럼 가져오기 때문이다.
게시글 작성 여부와 상관없이 "우리 사이트에 가입한 모든 회원 목록과, 그들이 쓴 글의 제목"을 보고 싶을 때 사용한다.
-- member 테이블(m)을 기준으로 왼쪽(LEFT)에 두고 모두 다 가져온다.
SELECT
m.author_name AS '회원이름',
a.title AS '작성한 글 제목'
FROM member AS m
LEFT JOIN article AS a
ON m.member_id = a.member_id;
[실행 결과]
왼쪽 테이블(member)에 있는 '이초보'의 이름도 무조건 출력된다. 단, '이초보'는 작성한 글이 없으므로 '작성한 글 제목' 칸에는 NULL(빈칸)이 표시된다. 이를 응용하면 글을 한 번도 쓰지 않은 유령 회원을 색출할 때 유용하다.
정리
1. 테이블을 설계할 때는 중복을 막기 위해 외래키(FOREIGN KEY)를 사용하여 정규화(분리) 한다.
2. 데이터를 조회할 때는 분리된 테이블을 ON 조건(주로 식별자 ID)을 기준으로 조인(결합) 하여 필요한 데이터만 뽑아낸다.