김영한님 강의와 다른 여러 스프링 강의에서 DB와 매핑하기 위한 객체를 생성하는 경우 숫자 타입에 Long을 사용하는 것을 볼 수 있었다. 더 자세하게는 “회원” 엔티티의 AUTO_INCREMENT
인 PK
값을 Long
타입으로 선언했다. 회원 도메인의 레코드 수가 21억개 이상이 될 수 있어서 테이블 컬럼 타입입을 BIGINT로 선언해서 그런것일까?
Integer가 아닌 Long 타입을 사용하는 이유가 궁금해서 여러 블로그의 글을 살펴봤는데 내가 확인해 본 블로그 글에서는 모두 같은 내용을 담고 있었다.
- Wrapper 클래스는 기본 값으로 null을 가진다.
- Long은 Integer보다 넓은 범위를 표현한다.
뭔가 가려움이 해소되지 않는다..
☁️ Wrapper 클래스 사용
1번은 나도 겪어본 문제이다 ORM을 사용할 때, 엔티티의 프로퍼티 타입을 primitive 타입으로 선언한 경우 해당 컬럼의 데이터가 존재하지 않더라고 0이라는 값이 할당된다. 애플리케이션 레벨에서 해당 컬럼 데이터의 존재 유무를 통해 로직의 분기가 생긴다면, 예상하지 못한 방향으로 프로그램이 동작할 수 있다.
primitve 타입과 reference 타입의 null 저장 유무는 항상 유의해서 개발해야 하는 특징이라고 생각한다.
☁️ 더 넓은 범위의 데이터 저장
문제는 2번이다. 회원 엔티티에서 왜 굳이 더 넓은 범위를 표현하는 Long 타입을 사용해야 하는지 잘 이해가 가지 않는다. Long 타입과 매핑되는 DB의 컬럼이 BIGINT가 아닌 경우 Integer 자료형으로도 저장 범위를 충분히 커버할 수 있을 거라는 생각이 들었다.
회원 테이블의 설계와 비교하며 생각해보자.
아래의 요구사항 정도를 가지는 회원 테이블이 존재한다고 가정했을 때 기본 키를 어떻게 가져가야 할까
- 회원 테이블은 범위 검색이 자주 발생하는가? ❌
- 동등 비교를 통한 단일 레코드 검색이 자주 발생하는가? ✅
만약 회원 테이블의 기본 키가 자연키(AUTO_INCREMENT)를 사용한다면?
MySQL에서는 회원 테이블에 저장되는 레코드들은 PK인 자연키를 통해 클러스터링 된다. 클러스터링 인덱스의 장점은 범위 검색에서 디스크를 순차탐색할 수 있다는 것. 하지만 범위 검색이 아닌 동등 비교를 통한 레코드 검색이 자주 발생하는 회원 테이블에서는 자연키도 합리적인 선택이다.
AUTO_INCREMENT 옵션으로 지정된 컬럼은 음수가 올 수 없기 때문에 unsigned int 타입을 사용하여 42억까지의 숫자를 담을 수 있게 설정하거나, BIGINT를 사용하는 것이 좋아 보인다.
위 상황을 토대로 정리해보면
- 회원 테이블의 PK는 최대 42억까지의 정수 타입을 가진다 - Long 매핑
- 회원 테이블의 PK는 최대 BIGINT(8 Byte)까지의 정수 타입을 가진다 - Long 매핑
이래서 Long타입을 사용한 것 같다.
'의문과 실험' 카테고리의 다른 글
제네릭은 왜 Lower Bounded를 지원하지 않을까? 와일드카드의 사용처는? (1) | 2024.01.09 |
---|---|
메인 메서드에 대한 고찰 (0) | 2024.01.03 |
Monitor와 Synchronized 동작 알아보기 (1) | 2024.01.01 |
상속 시, 오버라이딩된 메서드의 접근제어자는 왜 확장만을 허용할까 (0) | 2023.12.19 |
[Spring] 프로젝트에서 IO를 줄여 성능을 개선해보자 (0) | 2023.10.04 |