[JPA] 기본 키(primary key)와 매핑
복습
https://shins99.tistory.com/111
[Spring Boot] 페이징(paging)
복습 https://shins99.tistory.com/109 [JPA] 영속성 컨텍스트 영속성 컨텍스트란? 영속성 컨텍스트는 엔티티를 영구 저장하는 환경이라는 뜻이다. 영속성 컨텍스트는 애플리케이션과 DB 사이에서 객체를
shins99.tistory.com
기본 키(Primary key)?
- 주 키 또는 프라이머리 키라고 하며, 관계형 데이터베이스에서 레코드의 식별자로 가장 적합한 것으로 선택, 정의된 후보 키
기본키(primary key) 매핑하는 방법
- 총 2가지로 직접 할당과 자동 생성이 존재
- 직접 할당 : @Id 어노테이션만 사용하여 Id값을 직접할당
- 자동 생성 : @Id와 @GeneratiedValue를 사용하여 원하는 키 생성 전략을 선택
자동 생성의 키 생성 전략은 4가지로 구분됨
키 생성 전략
- IDENTITY : 데이터베이스에 위임 (MYSQL)
- SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용 (ORACLE)
- TABLE : 키 생성용 테이블 사용 (모든 DB에서 사용)
- AUTO : dialect(방언) 설정에 따라 자동 지정 (기본값)
IDENTITY 전략
@Id
@Generatedvalue(strategy = GenerationType.IDENTITY)
private Long id;
- 기본 키 생성을 데이터베이스에 위임하는 전략
(주로MySQL, PostgreSQL, SQL Server, DB2에서 사용)
- DB가 기본 키를 알아서 생성 해주므로 엔티티 값을 넣어줄 때 id 값을 빼고 값을 세팅가능
(엔티티의 생성자가 id 필드를 매개변수로 받지 않아도 됨)
SEQUENCE 전략
- 데이터베이스 시퀀스를 사용하여 기본키를 생성하는 전략
@Entity
@SequenceGenerator(
name = "MEMBER_SEQ_GENERATOR",
sequenceName = "MEMBER_SEQ", // 매핑할 DB 시퀀스 이름
initialValue = 1, allocationSize = 1)
public class Mamber {
@Id
@Generatedvalue(strategy = GenerationType.IDENTITY)
private Long id; }
시퀀스
- 일련번호를 생성하는 특수한 객체로, 일련번호를 하나하나씩 증가시키며 생성함
- 생성된 일련번호를 기본키로 사용하는 것이 SEQUENCE 전략
(주로 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용)
속성 값
속성 | 설명 | 기본값 |
name | 식별자 생성기 이름 | 필수 |
sequenceName | 데이터베이스에 등록되어 있는 시퀀스 이름 | hibernate_sequence |
initialValue | DDL 생성 시에만 사용. 시퀀스 DDL을 생성할 때 처음 시작하는 수를 지정한다 |
1 |
allocationSize | 시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용) | 50 |
catalog, schema | 데이터베이스 catalog, schema 이름 |
- allocationSize의 값은 기본값 50
- 기본값을 사용하면 sequence 호출마다 50씩 증가
- 데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값 을 반드시 1로 설정해야 함
allocationSize 기본값이 50인 이유?
- JPA는 시퀀스에 접근하는 횟수를 줄이기 위해 allocationSize를 사용
- allocationSize로 설정한 값 만큼 한번에 시퀀스 값을 증가시키고 나서, 그만큼 메모리에 시퀀스 값을 할당함
- allocationSize가 50이라면, 시퀀스를 한 번 조회 시 50을 증가시킨 다음에, 1~50 까지는 메모리에서 식별자를 할당,
51이 되면 시퀀스 값을 100으로 증가시킨 다음 51~100까지 메모리에서 식별자를 할당함
- 시퀀스 값을 선점하므로 여러 JVM에서 동시에 동작해도 기본 키 값이 충돌하지 않는다는 장점 존재
- 데이터베이스에 직접 접근해서 데이터를 등록할 때 시퀀스 값이 한번에 많이 증가하므로, 데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값 을 반드시 1로 설정해야 함
TABLE 전략
- 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략
- 모든 데이터베이스에 적용 가능하지만 성능이 떨어짐
@Entity
@SequenceGenerator(
name = "MEMBER_SEQ_GENERATOR",
sequenceName = "MEMBER_SEQ", // 매핑할 DB 시퀀스 이름
initialValue = 1, allocationSize = 1)
public class Mamber {
@Id
@Generatedvalue(strategy = GenerationType.IDENTITY)
private Long id; }
|
|
|
|
|
|
|
|
|
|
|
|
|
public class Member { |
|
|
|
|
|
|
|
private Long id; |
|
|
|
|
|
private String name; |
|
|
|
public Member(String name) { |
|
this.name = name; |
|
} |
|
} |
AUTO전략
- dialect(방언) 설정 값에 따라 위 셋의 전략중 하나를 자동으로 선택
(ex: Oracle이면 SEQUENC, MySQL이면 IDENTITY를 사용)
@GeneratedValue의 기본값은 AUTO이기에 AUTO 전략을 사용하면 속성값을 지정하지 않아도 됨
권장하는 기본키 선택 전략
기본 키 종류 | 설명 | 예시 |
자연키 | 비즈니스에 의미가 있는 키 | 주민등록 번호, 이메일 |
대리키 (대체키) | 비즈니스와 관계 없는 키 | AUTO_INCREMENT, 임의로 만들어진 키 |
기본 키 제약 조건
- null 이 아니다.
- 유일해야 한다.
- 변하면 안된다.
미래까지 기본키 제약 조건을 만족하는 자연키는 찾기 어렵기 때문에 대리키 사용이 권장됨
대리키(대체키)를 사용하는 것을 권장
|
// (Long 타입 + 대체키 + 키 생성전략) |
|
|
|
|
|
private Long id; |
추천
- 전략 선택이 고민이라면 데이터베이스에 맞춰서 선택하는 것이 좋음
- ex) MySQL = IDENTITY
ORACLE = SEQUENCE