데이터베이스 테이블을 생성할 때 PK 설정에 대해 Auto Increment를 사용할 지 , uuid를 사용할지 고민이 된다.
두 차이점을 명확히 파악하여 PK를 올바르게 설정하자.
AUTO INCREMENT
- auto increment는 키를 예측하기 쉬워 보안에 취약하다.
- int타입
- 분산 시스템에 적합하지 않다. ( 여러 데이터베이스가 있는 상황에서 insert를 한다고 생각하자. 별다른 동기화가 되어있지 않다면, 데이터베이스 A 가 insert를 받으면 1,2,3,4,5,6으로 키가 증가할거고, 데이터베이스 B 또한 insert 쿼리를 받으면 1,2,3,4,5,6으로 키가 증가할것이다. 즉 Duplicate Key가 발생하여 데이터 일관성에 문제가 생길 것이다. )
- uuid보다 메모리를 덜 차지하고, insert 시간이 적어 빠르다.
- 소규모 프로젝트에서 쓰임
UUID
- 128비트 길이의 데이터로, 5개의 16진수로 구성된 UTF-8 문자열이다.
- 보안에 좋다.
- UUID를 어디서든지 만들고 고유성을 보장할 수 있어 분산 시스템에 용이하다.
- 메모리 많이 차지함
- insert할 때 시간이 많이 걸린다.
- 성능의 저하를 일으킨다 (클러스터 인덱스의 정렬 비용이 많이 든다)
결론
단일 DB를 쓰면 AUTO_INCREMENT를 키로 쓰자. (성능, 메모리 측면에서 더 낫다.)
다중 DB를 사용하는 분산형 환경이면 데이터 일관성을 위해 UUID를 키로 쓰는 걸 고려해보자
< 추가 보충 설명 >
JPA를 시용해 auto increment를 사용하면 아래와 같은 소스코드가 나온다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@GeneratedValue(strategy = GenerationType.IDENTITY)
위의 애노테이션의 의미는 기본키 생성을 데이터베이스에 위임한다. (= auto_increment) 라는 의미이다.
영속성 컨텍스트는 엔티티를 영구 저장하는 환경인데 영속성 컨텍스트로 관리하기 위해서는 pk값이 무조건 필요하다.
원래 entityManager.persist()가 호출되면 바로 DB에 쿼리를 실행하는 게 아니라, 영속성 컨텍스트에 저장한 후에 트랜잭션의 커밋이 일어나면 그 때 DB에 저장된다.
auto_increment의 경우에는 entityManager.persist()가 호출될 때 바로 DB에 insert 쿼리를 실행한다.
이후에 JPA 내부에서 insert 쿼리 실행 후 바로 생성된 id값을 리턴받아서 id를 pk로 영속성 컨텍스트에 저장한다.
위와 같은 방식으로 기본키 영속성을 관리한다.
auto increment는 키를 예측하기 쉬워서 SQL Injection과 같은 공격에 취약하다는 단점이 있다.
분산환경에서는 UUID(Universally Unique ID)를 추천한다고 한다.
128비트 데이터로 100% unique하다고 보장은 못하는데 충돌 가능성이 굉장히 낮은 키다.
UUID는 자바 5에서부터 지원하고 있고 java.util.UUID 패키지에서 제공한다고 한다.
import java.util.UUID
...
@Id
@GeneratedValue(generator = "uuids")
@GenericGenerator(name= "uuid2", strategy = "uuid")
private UUID id;
위와 같이 쓸 경우 BINARY(16) 혹은 VARCHAR 타입을 가지게 된다.
기존 int타입으로 auto increment하는 것보다 메모리도 많이 쓰고 uuid 생성때문에 insert할 때 시간이 더 많이 걸린다.
'MySQL' 카테고리의 다른 글
51회 SQLD 4일 벼락치기 합격 후기 (2) | 2024.06.03 |
---|---|
[MySQL] DECIMAL, FLOAT, DOUBLE, BIT 소수점 표현 (0) | 2024.02.10 |
[MySQL] tinyint, smallint, int, bigint 비교 (2) | 2024.02.10 |
[MySQL] DATE, DATETIME, TIMESTAMP, TIME 차이 (0) | 2024.02.10 |