티스토리 뷰
이전 글에서 JPA 복합키의 사용법을 알아보았는데요, 이번에는 JPA에서 선호하는 키 방법에 대해 간단히 살펴보고자 합니다.
이전 글 : https://abbo.tistory.com/329
우선 제가 사용한 방법은 Java 에서는 long Wrapper 클래스인 Long 타입, MySQL 에서는 bigint 타입을 사용하였습니다.
가장 먼저 JPA의 인덱스 처리 상 조회에서는 문제가 빈번하게 일어나는 경우 크게 없습니다. 하지만 문제는 생성/수정/삭제에 일어나게 되는데요. 아래의 조건은 기본적으로 발생하는 조건입니다.
- JPA의 인덱스 처리는 B-Tree 알고리즘을 사용한다.
- Primary Key는 Unique하다.
- 복합키는 Tuple로 관리한다.
- Tuple은 B-Tree를 사용하지 않는다.
- 복합키는 인덱스이며 Unique한 값이다.
- Unique Key는 두 개 이상에 컬럼에 같이 걸려있는 값이다.
즉, 복합키는 Unique하며 Tuple로 인식이 되기 때문에 정렬에 큰 지장이 없다. 가 결론이 되겠습니다. 다만 성능에 지장이 있는 부분은 두 개 이상의 컬럼(Unique Key Set)이 아닌 각각의 컬럼에 걸린 경우 조회시 문제가 발생할 수도 있겠습니다.
정확한 예시를 위해 저번에 작성한 클래스를 다시 가져와보겠습니다.
@Entity
@Data
@IdClass(PushLogPK.class)
public class PushLog {
@Id
@Column(name = "user_id")
private Long userId;
@Id
@Column(name = "push_id")
private Long pushId;
private boolean clicked;
@Data
public static class PushLogPK implements Serializable {
private Long pushId;
private Long userId;
public PushLogPK() {}
}
public PushLog() {}
public PushLog(Long userId, Long pushId) {
this.userId = userId;
this.pushId = pushId;
}
}
위의 경우 pushId, userId 두 개의 set으로 조회를 하는 경우는 큰 문제가 되지 않습니다. 하지만, pushId 별로 조회를 하거나 userId 별로 조회를 하는 경우 인덱스가 형성되어 있지 않다면, 쿼리 성능에 지연이 있을 수 있습니다. 그렇게 되는 경우 DB에 직접 접근하여 인덱스를 추가해주어야 합니다.
추가로 equals(), hashCode() 메소드를 복합키 비교에서 사용하기 때문에 @Override 하여 설정하는 것이 좋습니다. 왜냐면 동등 비교로 인식을 하는 부분에서 문제가 발생하기 때문입니다.
즉, 아래의 경우는 성립되지 않습니다.
PushLog log1 = new PushLog(1L, 2L);
PushLog log2 = new PushLog(1L, 2L);
log1.equals(log2); // false -> 메모리 주소(hashCode)가 다름
그래서 아래와 같이 Override 함수를 추가해주면 편하지 않을까 합니다.
@Override
public boolean equals(PushLog pushLog) {
return this.userId.longValue() == pushLog.getUserId().longValue()
&& this.pushId.longValue() == pushLog.getPushId().longValue();
}
@Override
public int hashCode() {
return this.pushLogPK.hashCode();
}
요약하자면 아래와 같습니다.
장점
- 성능에 지장이 없다.
- 키를 조합하기 쉽다.
단점
- 조합된 키만을 사용해야 한다.
- equals(), hashCode() 함수를 구현해야 한다.
참고 문서
복합키 성능 비교 : https://developer-ping9.tistory.com/298
JPA에서 equals(), hashCode() 구현 이유 : https://modimodi.tistory.com/14
'Server' 카테고리의 다른 글
Amazon Linux 에서 자바 버전 변경하기 (0) | 2022.10.08 |
---|---|
build.gradle 에서 application.properties 값 사용하는 방법 (0) | 2022.10.07 |
유료로 대체되는 Docker Desktop 대체하기 (0) | 2022.10.06 |
[Java] 소수점 처리하기 (0) | 2022.09.26 |
Shell 파일에서 *.jar 파일 백그라운드 실행 (0) | 2022.09.21 |
Firebase Push 와 관련된 적용사항 (0) | 2022.09.19 |