Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

기본 키(PK) 매핑 본문

인프런/[인프런] 자바ORM 표준 JPA 프로그래밍

기본 키(PK) 매핑

Seung__ 2021. 8. 9. 21:59

1. PK 매핑 방법


  • 직접 할당 : @Id만 사용
  • 자동 생성 : @GeneratedValue
    - IDENTITY: 데이터베이스에 위임, MYSQL
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;​

    - SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, ORACLE --> @SequenceGenerator 필요
    - TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용 --> @TableGenerator 필요
    - AUTO: 방언에 따라 자동 지정, 기본값

 

 

2. IDENTITY


  • 기본 키 생성을 DB에 위임 : 너가 알잘딱해
  • MySQL, PstgreSQL, SQL Server, DB2에서 사용
  • JPA는 보통 transaction commit 시점에 INSERT SQL 실행
  • AUTO_INCREMENT는 DB에 INSERT SQL을 실행한 이후에 ID값을 알 수 있음
  • IDENTITY 전락은 em.persist()시점에 즉시 INSERT SQL 실행하고 DB에서 식별자 조회함.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
  • IDENTITY 전략으로 생성된 것을 확인할 수 있다.
Hibernate: 
    
    create table Member (
       id bigint generated by default as identity,
        name varchar(255),
        primary key (id)
    )
  • 이 상태에서 방언을 바꿔보면...?(MySQL로 변경)
    - auto_increment로 생성됨.
  • Hibernate: create table Member ( id bigint not null auto_increment, name varchar(255), primary key (id) ) engine=MyISAM​
  • IDENTITY 전략은 개발자가 id를 넣지 않고 DB에 insert를 함.
  • id가 null로 INSERT SQL이 날라가면 DB에서 값을 세팅해줌.
  • 즉 DB에 데이터가 들어가야 ID를 알 수 있음.
  • 어? 근데 영속성 컨텍스트에서 관리되려면...PK가 필요한데...?PERSIST한다고 DB에 들어가는것도 아닌데..?
  • 그래서..IDENTITY 전략에 한해서만, em.psersist(entity) 호출 하자마자 DB에 바로 SQL 날려버림....!!
  • 그리고 id값을 return 받기 때문에 persist 시점에 id값을 알 수 있게 된다.
  • 흠..지연쓰기 이점이 없는데????->단점!

 

 

3. SEQUENCE


  • DB에 있는 sequence object를 통해 값을 생성함.
  • 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트(예: 오라클 시퀀스)
  • 따라서 SEQUENCE 전략은 hibernate_sequence를 생성한다.
  • 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
Hibernate: create sequence hibernate_sequence start with 1 increment by 1

Hibernate: 
    call next value for hibernate_sequence

  • 만약 테이블 마나 시퀀스 따로 관리하고 싶으면
  • @SequenceGenerator, @GeneratedValue(generator = "")
@Entity
@SequenceGenerator(name = "member_seq_generator", sequenceName = "member_seq")
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq")
    private Long id;
Hibernate: create sequence member_seq start with 1 increment by 50

Hibernate: 
    call next value for member_seq
  • @SequenceGenerator
    - 주의 : allocationSize의 기본값= 50
속성 설명 기본값
name 식별자 생성기 이름. 필수
sequenceName 데이터베이스에 등록되는 시퀀스 이름 hibernate_sequence
initialValue DDL 생성 시에만 사용됨. 시퀀스 DDL을 생성할 때 처음 1 시작하는 수를 지정한다. 1
allocationSize 시퀀스 한 번 호출에 증가하는 수
(성능 최적화에 사용.
데이터 베이스 시퀀스 값이 하나 씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 함
50
catalog, schema 데이터베이스 catalog, schema이름  
  • em.persist(entity)를 할 때 영속성 컨텍스트에 들어가야 하는데, PK가 필요해!
  • 그럼 persist전에 시퀀스를 먼저 가져와서 id값을 넣고 영속성 컨텍스트에 올라감. 이 시점에 SQL은 안날라감
  • SQL은 commit 시점에 날라감.
  • 즉 한방에 SQL 날리기 가능
  • 흠 근데 ID 가져올라고 계속 네트워크타니 성능 문제 없을까...?

3-1) allocationSize : 기본값 50

  • 매번 DB에서 받아오면 성능문제 있으니 미리 DB에 50개 미리 올려둠.
    메모리에서 하나씩 갯수에 맞춰 id소모. 50개 다차면 DB에 다시 50개 올려둠.
  • 여러 개를 PERSIST하는 경우  처음 두 번만 call next value for DB_SEQ를 호출하고
    나머지는 메모리에서 호출한다.
  • 객체 개수가 쌓여서 id가 51이 되면 call next value for DB_SEQ 호출함.
  • 보통 50~100정도가 적당.
  • 값을 미리 올려두는 방식이기 때문에 서버가 여러개여도 미리 확보를 해두기 때문에 문제 없음.
  • ID 값을 call next value 를 호출할 때 받기 때문에 어디까지 쓸 수 있는지 알고있음.

 

4. TABLE 전략


  • 키 생성 전용 table을 하나 만들어서, 데이터베이스 시퀀스를 흉내냄
  • 장점 : 모든 데이터베이스에 적용이 가능
  • 단점 : 성능 ㅜㅜ
@Entity 
@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;
  • log
create table MY_SEQUENCES ( 
 sequence_name varchar(255) not null, 
 next_val bigint, 
 primary key ( sequence_name ) 
)
  • 운영에서 쓰기 부담스러움....

 

 

5. 권장하는 식별자 전략


  • 기본 키 제약 조건은 : null이 아니고, 유일하고, 변하면 안된다.(어려움..)
  • 정~~~~~~~말 나중까지 변하면 안됨.
  • 미래까지 이 조건을 만족하는 자연지를 찾기 어려움..(주민번호, 전화번호 등등)
  • 따라서 비즈니스와 전~혀 상관없는 대리키(대체키)를 사용하자.
  • 주민번호도 안됨!
  • 권장 : Long형(10억 넘어도되게) + 대체키 + 키 생성 전략 사용.
Comments