2차 프로젝트 테이블 설계 - 유저테이블과 e커머스 서비스테이블들의 연관
users 테이블의 user_id는 자동증가하는 id고 login_id라고 회원가입시 사용하는 아이디 컬럼이 따로 있는데 user_id를 fk로사용해야하는거야? login_id를 사용해야하는거야?
정답: user_id (자동 증가 PK) 를 FK로 사용하는 것이 정답입니다.
login_id 는 절대 FK로 사용하지 않는 게 맞습니다. 👍
왜 user_id(PK) 를 FK로 써야 할까?
📌 1. 변경 가능 여부 차이
| 컬럼 | 변경 가능 여부 | FK로 적합? |
|---|---|---|
user_id (자동 증가 PK) |
❌ 변경되면 안 됨 | ✔ 사용 |
login_id (사용자 입력) |
✔ 변경될 수 있음 | ❌ 사용하면 안 됨 |
사용자가 닉네임처럼 login_id를 변경할 수도 있고, 정책에 따라 아이디 변경 기능을 주는 서비스도 있습니다.
즉, 변경될 수 있는 값은 FK로 절대 쓰면 안됩니다.
📌 2. 성능 및 인덱스 효율
FK는 보통 다음 특성을 가져야 합니다:
-
정수형 (INTEGER / BIGINT)
-
고정 길이
-
개별 인덱싱 비용이 낮음
login_id 는 문자열 비교라:
-
인덱스 크기가 커지고
-
조인 속도가 느려지고
-
저장 공간도 증가합니다.
반면 user_id(BIGINT)는:
✔ 빠른 검색
✔ 빠른 조인
✔ 인덱스 효율 최고
📌 3. 비식별자 키(Natural Key) vs 식별자 키(Surrogate Key)
| 타입 | 예시 | 사용 상황 |
|---|---|---|
| Natural Key | login_id, email | 의미 있는 값이지만 변경될 수 있음 |
| Surrogate Key | user_id (INT AUTO_INCREMENT) | 의미는 없지만 불변이고 안정적 |
관계형 설계 원칙:
FK는 Surrogate Key를 사용해야 한다.
📌 4. 확장성
나중에 소셜 로그인(Google, Apple, 카카오)이 붙으면 로그인 ID 구조가 바뀔 수 있음.
| 로그인 방식 | login_id 형태 |
|---|---|
| 일반 회원가입 | user@domain.com 또는 username |
| 구글 로그인 | google-oauth-token-xxxxxxxx |
| 카카오 로그인 | kakao:12391239123 |
→ login_id가 설정 방식에 따라 바뀌고 전혀 통일되지 않음.
하지만 user_id는 변하지 않음.
🚀 Best Practice 테이블 구조
CREATE TABLE users (
user_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 내부 전용 식별자
login_id VARCHAR(255) UNIQUE NOT NULL, -- 사용자가 사용하는 로그인 ID
password_hash VARCHAR(255),
email VARCHAR(255),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
그리고 외부 테이블들은:
orders.user_id → FK(users.user_id)
payments.user_id → FK(users.user_id)
refunds.user_id → FK(users.user_id)
cart.user_id → FK(users.user_id)
요약
| 비교 항목 | user_id(PK) | login_id |
|---|---|---|
| 불변성 | ✔ 안정적 | ❌ 변경 가능 |
| 조인 성능 | ✔ 빠름 | ❌ 문자열 비교 비용 큼 |
| 인덱스 효율 | ✔ 우수 | ❌ 비효율 |
| 외래키 적합성 | ✔ Best choice | ❌ Bad practice |
🎯 결론
모든 연관 테이블에서는 FK로
user_id (자동 증가 PK)를 사용해야 하고, login_id는 오직 인증 용도로만 사용해야 합니다.
원하면 다음 단계로:
📍 Multi-login(소셜 로그인 포함) 구조까지 확장한 auth/identity 테이블 설계 이어갈까요? 😎
댓글
댓글 쓰기