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 테이블 설계 이어갈까요? 😎

댓글

가장 많이 본 글