PostgreSQL은 MySQL처럼 AUTO_INCREMENT
가 없고, 시퀀스(sequence) 객체를 사용하는 DB다.
그래서 GenerationType.SEQUENCE
전략이 자연스럽고, 성능이나 트랜잭션 측면에서도 더 유리하다.
JPA가 DB에 등록된 시퀀스 객체를 참조해서
다음 ID 값을 미리 조회 (select nextval('시퀀스명')
)
그 값을 @Id
필드에 미리 할당한 후
INSERT
실행 → 이때는 id를 이미 알고 있음
즉, DB가 자동으로 채우는 IDENTITY와 달리,
JPA가 먼저 값을 가져와서 넣고 저장하는 구조이다.
@Entity
@SequenceGenerator(
name = "conti_seq_generator", // JPA 내부에서 참조할 이름
sequenceName = "conti_seq", // 실제 DB의 시퀀스 이름
initialValue = 1,
allocationSize = 1
)
class Conti(
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "conti_seq_generator")
val id: Long? = null,
...
)
conti_seq
시퀀스를 호출해서 id를 먼저 받아오고,그 id를 넣어서 insert 한다.CREATE SEQUENCE conti_seq START WITH 1 INCREMENT BY 1;
DB 안에서 자동으로 숫자를 1씩 증가시키는 객체.
예를 들어 어떤 테이블에 새로운 데이터를 넣을 때, id
값이 중복되면 안 됨.
이때 DB는 시퀀스
라는 별도의 객체를 사용해서 ID를 순차적으로 자동 생성.
그리고 PostgreSQL에서는 AUTO_INCREMENT
대신 시퀀스를 기본 제공 방식으로 사용.
@GeneratedValue(strategy = GenerationType.IDENTITY)
는
MySQL, MariaDB, H2 등에서 기본적으로 잘 작동.
이 DB들은 AUTO_INCREMENT 방식이 내장돼 있어서, IDENTITY 전략이 잘 맞음.
그래서 특별한 설정 없이 @Id + @GeneratedValue(strategy = IDENTITY)
만으로 OK.
그런데 PostgreSQL은 시퀀스 기반이라
AUTO_INCREMENT가 없고, 대신 SEQUENCE 객체를 쓴다.
그래서 JPA에서는 PostgreSQL과 잘 맞는 방식으로
@GeneratedValue(strategy = GenerationType.SEQUENCE)
를 써야 한다.
그리고 그 시퀀스의 이름, 설정 등을 명시하려면 →
@SequenceGenerator
를 꼭 같이 붙여야 한다.
항목 | IDENTITY | SEQUENCE |
---|---|---|
ID 생성 위치 | DB에서 생성 | JPA가 시퀀스를 통해 미리 조회 |
INSERT 방식 | ID 없이 INSERT → DB가 채워줌 | ID를 채운 후 INSERT |
단점 | INSERT 이후에만 ID를 알 수 있음 | 시퀀스 객체가 필요함 |
장점 | 설정이 간단하고 직관적임 | 미리 ID 확보 가능 → 병렬 처리 성능 우수 |
PostgreSQL 적합도 | ❌ 비추천 (지원은 하지만 비효율) | ✅ PostgreSQL 기본 메커니즘과 일치 |
PostgreSQL도 IDENTITY 지원은 한다.
PostgreSQL은 10버전부터 GENERATED AS IDENTITY
문법을 지원하면서,
@GeneratedValue(strategy = IDENTITY)
도 문제 없이 작동한다.
하지만
항목 | IDENTITY | SEQUENCE |
---|---|---|
성능 | 다소 느림 (ID는 INSERT 후에만 알 수 있음) | INSERT 전에 ID를 확보 → 병렬 처리 성능 우수 |
확장성 | 제약 있음 (병렬 환경에서 충돌 가능성 있음) | 고급 설정 가능, allocationSize 조절로 성능 최적화 가능 |
추천도 | PostgreSQL에선 비추천 | PostgreSQL의 기본 메커니즘과 일치하므로 권장 |
그래서 단순한 서비스에는 IDENTITY도 충분하지만,
앞으로 만드는 서비스는 확장성, 성능, 실무 유사성 측면에서
SEQUENCE를 써서 설계하는 게 훨씬 좋다.