일대일(1:1) 관계는 한 테이블의 하나의 행이, 다른 테이블의 정확히 하나의 행과만 연결되는 관계를 의미한다.
이처럼 양쪽 모두에서 "최대 1개"만 연결되는 관계를 1:1 관계라고 부른다.
실무에서는 1:1 관계가 1:N 관계보다 훨씬 덜 등장한다. 그 이유는 간단하다.
1:1 관계인 두 엔티티는 대부분 하나의 테이블로 합쳐도 무리가 없기 때문이다.
그럼에도 굳이 테이블을 분리해서 1:1 관계로 설계하는 데는 전략적인 이유가 있다.
다음과 같은 member 테이블을 생각해본다.
| 컬럼명 | 설명 |
|---|---|
member_id |
PK, 회원 ID |
name |
회원 이름 |
email |
이메일 |
phone |
연락처 |
intro |
자기소개(긴 텍스트) |
homepage_url |
개인 홈페이지 주소 |
mbti |
MBTI 성격 유형 |
profile_image |
프로필 이미지 URL 혹은 바이너리 데이터 |
문제는 intro, homepage_url, profile_image 같은 컬럼은 로그인, 권한 체크, 단순 회원 목록에서는 거의 사용하지 않는다는 점이다.
만약 이런 컬럼들이 모두 한 테이블에 섞여 있으면, 단순히 이름과 이메일만 조회하는 쿼리도 큰 행 전체를 디스크에서 읽어 와야 한다. 이때 다음과 같이 테이블을 분리할 수 있다.
-- 핵심 정보만 갖는 member 테이블
CREATE TABLE member (
member_id BIGINT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
phone VARCHAR(20)
);
-- 상세 프로필 정보는 별도 테이블로 분리
CREATE TABLE member_profile (
member_id BIGINT PRIMARY KEY,
intro TEXT,
homepage_url VARCHAR(255),
mbti VARCHAR(4),
profile_image VARCHAR(255),
CONSTRAINT fk_member_profile_member
FOREIGN KEY (member_id) REFERENCES member(member_id)
);
이렇게 하면,
member만 읽는다.member + member_profile를 조인한다.