본문 바로가기
springboot/jpa

JPA 기본키(PK) 매핑 전략

by cactuslog 2025. 6. 23.
JPA에서 기본키(PK) 매핑 전략은 엔티티의 식별자를 어떻게 생성하고
관리할지를 결정하는 매우 중요한 설계 요소이다.

 

기본키 매핑 annotation

•   @Id

•   @GeneratedValue

@Entity
public class MemberEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    ...
}

 

•   기본키를 직접 할당할 때는 @Id만 사용한다.

 

•   자동 생성을 할 경우 @GeneratedValue를 사용하고 전략을 설정한다.

strategy 설명
AUTO 방언에 따라 자동 지정, strategy 기본값
IDENTITY 데이터베이스에 위임, MYSQL
SEQUENCE 데이터베이스 시퀀스 오브젝트 사용, ORACLE
TABLE 키 생성용 테이블 사용, 모든 DB에서 사용

IDENTITY 전략

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

 

•  기본키 생성을 데이터베이스에 위임한다.

 

•  INSERT 이후에 PK가 결정된다.

 

•  영속성 컨텍스트에서 관리되려면 pk가 있어야 한다.

 

•  이를 위해 identity전략은 persist 시점에 INSERT쿼리가 날라간다.

 

•  따라서 identity 전략에서는 모아서 batch insert를 할 수 없다.

 

•  사실 한 트랜잭션 안에서 적은 INSERT 쿼리가 여러 번 네트워크를 통신을 탄다고 해도, 그렇게 큰 성능 차이가 나지 않는다.

SEQEUNCE 전략

•  DB의 시퀀스 객체를 사용한다.

 

•  Oracle, PostgreSQL 등 지원, MySQL 사용 불가

@SequenceGenerator(name = "MEMBER_SEQ_GENERATOR",
sequenceName = "MEMBER_SEQ",
initialValue = 1, allocationSize = 1)
@Entity
public class MemberEntity {

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
	private Long id;
	...

@SequenceGenerator 

속성 설명
name sequenceGenerator 이름, 필수 설정
sequenceName 데이터베이스에 등록되어 있는 시퀀스 이름
initialValue 시퀀스 DDL을 생성할 때 처음 시작하는 수 지정, 기본값 1
allocationSize 시퀀스 한 번 호출에 증가하는 수
성능 최적화를 위해 사용, 기본값 50
데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 한다
catalog, schema 데이터베이스 catalog, schema 이름

 

•   성능 최적화를 위해 allocationSize 설정으로 사전에 여러 ID를 미리 가져온다.

 

•   시퀀스 전략은 persist할 때 영속성 컨텍스트에 넣으려면 pk가 필요하므로, 시퀀스 call을 통해 다음 숫자를 얻어온다.

[Hibernate] 
    select
        next value 
    for
        member_seq_generator

 

•   allocationSize를 크게 설정하여 미리 점유해서 persist 시점에 DB 접근 없이 영속성 컨텍스트에 바로 저장할 수 있지만, 재배포하면 메모리에서 날라가기 때문에 숫자 범위 사이에 빈 공간이 생긴다.

 

•   여러 웹서버가 동시에 호출하더라도, 각 서버가 숫자를 미리 확보하고 있는 것이라 문제되지 않는다.

TABLE 전략

•   키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내 내는 전략

 

•   매 INSERT 전마다 키 테이블을 조회하거나 업데이트 해야 하고 동시성 이슈로 성능이 낮다.

 

•   실무에서는 될 수 있으면 사용하지 않는다.


권장하는 기본키 설계

•   기본 키는 테이블의 각 레코드를 유일하게 식별해야 하므로 다음과 같은 조건을 반드시 만족해야 한다.

제약 조건  설명
NOT NULL 값이 반드시 존재해야 함
UNIQUE 전체 테이블에서 중복되면 안 됨
IMMUTABLE 한 번 정해지면 절대 바뀌면 안 됨

 

•   미래까지 이 조건을 만족 하는 자연키를 찾기는 어렵다.

 

•   자연키(natural key)란 현실 세계에서 이미 존재하는 고유 식별값을 그대로 PK로 사용하는 것이다. ex) 주민등록번호, 이메일

 

•   유일해 보여도 시간이 지나면 변경 가능성이 존재한다.

 

•   개인정보보호, 식별 정책 등으로 인해 변경 or 삭제 요구 발생

실제 사례: 주민등록번호를 키로 설정하였는데, 정부 가이드에서 보안상 db에 주민번호를 저장하면 안된다고한 상황,
해당 테이블 pk만 문제가 아니라, 그 회원 테이블과 연관된 나머지 테이블이 pk를 외래키로 들고 있기 때문에 수십 개 테이블을 바꿔야 하는 문제가 발생

 

•    기본키는 비지니스와 상관없는 키를 쓰는게 좋다.

Long형 + 대체키 + 키 생성전략을 사용하자

•   대체키(surrogate key)는 DB 내부적으로 생성하는 무의미한 숫자 ID를 PK로 사용하는 방식이다.

id BIGINT AUTO_INCREMENT

 

•   의미 없는 숫자지만 유일하고, null이 아니고, 미래에도 변하지 않는다.

'springboot > jpa' 카테고리의 다른 글

JPA 필드와 컬럼 매핑  (0) 2025.06.23
JPA DB 스키마 자동 생성 이상과 현실  (0) 2025.06.22
JPA 클래스와 테이블 매핑 @Entity, @Table  (1) 2025.06.22
JPA 영속성 관리  (1) 2025.06.20
JPA를 왜 사용해야 하는가?  (0) 2025.06.18