개념과 배경

InnoDB는 데이터를 클러스터형 인덱스 기준으로 저장하는 스토리지 엔진임 대부분의 테이블에서 이 클러스터형 인덱스는 프라이머리 키가 담당함 사용자가 명시적으로 PK를 정의하지 않은 경우에도 InnoDB는 테이블에 클러스터 키를 반드시 갖도록 함 이때 결정 규칙이 존재함

  • 먼저 NOT NULL 제약을 가진 유니크 인덱스가 있으면 그것을 클러스터형 인덱스로 사용
  • 그런 인덱스가 없으면 내부 6바이트 row_id를 생성해 숨김 PK로 사용

세컨더리 인덱스는 항상 클러스터 키를 포함하여 룩업을 수행함 따라서 명시적 PK가 없더라도 내부적으로는 클러스터 키가 존재하며 저장과 탐색 경로의 기준으로 동작함

핵심 개념 정리

  • 클러스터형 인덱스 테이블의 물리적 정렬 기준이 되는 인덱스 PK 또는 그에 준하는 키가 담당
  • 명시적 PK 부재 시 동작 NOT NULL 유니크 인덱스가 있으면 해당 인덱스를 클러스터 키로 채택 없으면 6바이트 숨김 row_id 생성 후 클러스터 키로 사용
  • 세컨더리 인덱스 리프에 클러스터 키 값을 포함하여 최종 레코드에 도달하는 구조
  • FK 제약 참조 대상은 PK 또는 유니크 키가 필요 숨김 row_id는 외부에서 참조 불가

장점

  • 설계 유연성 확보 로우의 고유 식별을 강제하지 않음 중복 허용 설계 가능 로그나 임시 적재 같은 일회성 데이터에 적합
  • 스키마 선언 단순화 별도 PK 칼럼을 정의 관리하지 않음 내부적으로는 InnoDB가 식별자를 보유하므로 개발자는 이를 의식하지 않아도 됨
  • 내부 식별 자동 관리 내부 row_id로 일관된 클러스터링 확보 별도의 AUTO_INCREMENT 칼럼을 두지 않아도 되는 선택지 존재

단점

  • 클러스터링 효율 저하 가능성 워크로드가 특정 칼럼 기준 범위 조회 중심인 경우 해당 칼럼을 PK로 잡을 때보다 페이지 지역성과 스캔 효율이 떨어질 수 있음 숨김 row_id 기준 정렬은 업무 키와 무관하므로 의도한 액세스 패턴과 불일치
  • 무결성 및 중복 제어 부재 PK나 유니크 키가 없으면 동일 데이터의 다중 삽입을 제약하기 어려움 중복 제거와 정합성 보장이 애플리케이션 책임으로 이동
  • FK 사용 제약 FK는 참조 대상이 PK 또는 유니크 키여야 함 숨김 row_id는 외부에서 참조할 수 없어 실질적으로 FK 기반 관계형 모델 구성 난이도 상승
  • 운영 관리와 확장성 저하 대용량 환경에서 주 식별자 부재는 트러블슈팅과 튜닝 지점을 모호하게 만듦 인덱스를 다수 추가해도 클러스터 키가 워크로드와 맞지 않으면 성능 이득이 제한적일 수 있음
  • 예측 불가능성 증가 숨김 row_id는 사용자 가시성과 제어가 없어 클러스터링 순서나 재배치 영향 분석이 어려움

언제 PK 생략을 고려할 수 있는가

  • 로그 수집과 임시 적재처럼 개별 로우 식별이 비핵심이고 중복 허용 전제가 있는 경우
  • FK를 사용하지 않고 일회성 처리 후 주기적 파티션 드롭이나 벌크 삭제로 관리하는 테이블
  • 접근 패턴이 대부분 단순 삽입과 기간 기반 일괄 삭제이며 조회가 제한적인 워크로드

이 경우에도 최소한의 제약을 두는 편이 안전함

  • 업무적으로 유일해야 하는 칼럼 조합에는 유니크 인덱스 부여 권장
  • 파티션 키 또는 보존 기간 기준의 관리 전략을 명확히 문서화
  • 조회가 늘거나 관계가 필요해질 가능성에 대비해 스키마 변경 경로를 마련

실무 권장 사항과 트레이드오프

  • OLTP 워크로드 기준 기본값은 명시적 PK 부여 단조 증가 surrogate key를 PK로 채택해 클러스터 페이지 분할 비용을 낮추는 전략 선호
  • 명시적 PK는 다음 이점을 제공 클러스터 인덱스가 워크로드 접근 패턴을 반영하도록 설계 가능 세컨더리 인덱스의 참조 대상이 명확해 룩업 비용 예측 용이 FK 구성과 무결성 보장 단순화
  • PK 생략은 스키마와 코드가 단순해 보이지만 운영 단계에서 성능 최적화와 무결성 확보 비용이 커질 수 있음

정리

  • InnoDB는 항상 클러스터형 인덱스를 필요로 함 명시적 PK가 없으면 NOT NULL 유니크 키를 우선 사용하고 그마저 없으면 6바이트 숨김 row_id를 생성해 대체함
  • PK 없이 인덱스만 두는 설계는 특수 목적에서만 고려 로그와 임시 저장 등 중복 허용과 낮은 정합성 요구의 시나리오에 한정하는 편이 안전
  • 일반적인 OLTP 환경에서는 명시적 PK가 사실상 필수 무결성 보장과 쿼리 최적화, FK 구성, 예측 가능한 성능 튜닝 측면에서 이점이 큼 결론적으로 PK를 두지 않는 선택은 예외적 상황으로 제한하고 대부분의 테이블에는 업무 맥락에 맞는 명시적 PK를 설계하는 것이 바람직함

참고자료