본문 바로가기
[Spring Boot]/[JPA]

[JPA] 기본 키(primary key)와 매핑

by 북방바다코끼리표범 2023. 10. 23.

복습

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; }

 

 

 
@Entity
 
@NoArgsConstructor
 
@TableGenerator(
 
name = "MEMBER_SEQ_GENERATOR",
 
table = "MY_SEQUENCES",
 
pkColumnValue = "MEMBER_SEQ", allocationSize = 1)
 
public class Member {
 
 
 
@Id
 
@GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
 
private Long id;
 
 
 
@Column
 
private String name;
 
 
 
public Member(String name) {
 
this.name = name;
 
}
 
}

AUTO전략


- dialect(방언) 설정 값에 따라 위 셋의 전략중 하나를 자동으로 선택

(ex: Oracle이면 SEQUENC, MySQL이면 IDENTITY를 사용)

@GeneratedValue의 기본값은 AUTO이기에 AUTO 전략을 사용하면 속성값을 지정하지 않아도 됨


 

권장하는 기본키 선택 전략

  
 
기본 키 종류 설명 예시
자연키 비즈니스에 의미가 있는 키 주민등록 번호, 이메일
대리키 (대체키) 비즈니스와 관계 없는 키 AUTO_INCREMENT, 임의로 만들어진 키

 

기본 키 제약 조건
  • null 이 아니다.
  • 유일해야 한다.
  • 변하면 안된다.

미래까지 기본키 제약 조건을 만족하는 자연키는 찾기 어렵기 때문에 대리키 사용이 권장됨

대리키(대체키)를 사용하는 것을 권장

 

 
// (Long 타입 + 대체키 + 키 생성전략)
 
@Id
 
@GenerateValue
 
private Long id;

추천

- 전략 선택이 고민이라면 데이터베이스에 맞춰서 선택하는 것이 좋음

- ex) MySQL = IDENTITY 

     ORACLE = SEQUENCE