1. JPA/Hibernate의 타입 매핑 구조
- JPA와 Hibernate는 Java 객체를 관계형 데이터베이스에 영속화할 때 다양한 타입 매핑 방식을 제공하며 대표적으로 다음 세 가지 범주가 있음
- 기본 타입(Basic Types): Integer, Long, String, Float, Enum 등과 같이 데이터베이스의 단일 컬럼에 매핑되는 타입
- 임베디드 타입(Embeddable Types): 여러 컬럼을 하나의 Java 컴포넌트로 그룹화해 매핑할 수 있음 i.g. 주소( Address)와 같은 객체가 여러 컬럼을 가질 때 사용
- 엔티티 타입(Entity Types): 데이터베이스의 테이블과 직접적으로 매핑되는, 각각의 식별자 (Primary Key)를 가지는 객체
2. 컬럼 타입의 컴팩트함이 중요한 이유
- 데이터베이스에서 동일한 페이지 (메모리 또는 디스크 단위)에 더 많은 행을 저장할 수 있음
- 인덱스와 자주 사용되는 테이블 페이지가 메모리에 더 잘 적재됨
- 대용량 데이터 처리 시 성능과 확장성, 비용 측면에서 매우 중요함
- i.g. 동일한 정보를 1바이트 (tinyint)로 저장할 수 있는데도 8바이트 (varchar 8)로 저장하면 메모리, 디스크, 네트워크 효율이 저하됨
3. Java Enum을 매핑하는 여러 전략
- JPA와 Hibernate에서 @Enumerated 어노테이션을 사용해 Enum 매핑 전략을 선택할 수 있음
3.1 EnumType.STRING
- Enum의 이름 (문자열 값, 예: "PENDING")이 데이터베이스 컬럼에 저장
- 가독성이 높고, 데이터만 보고도 의미를 쉽게 파악할 수 있음
- 단점은, enum 값이 길수록 더 큰 varchar 컬럼이 필요하고, 공간이 비효율적일 수 있음
3.2 EnumType.ORDINAL
- Enum의 순서 (ordinal, 0부터 시작하는 숫자)가 데이터베이스 컬럼에 저장
- 매우 컴팩트 (i.g. tinyint로 1바이트 사용 가능), 인덱스/저장 효율 최상
- 단점은 숫자만 보면 의미를 알 수 없음 (설명력이 떨어짐), Enum 순서 변경 시 데이터 불일치 위험
3.3 EnumType.ORDINAL + 설명 테이블 조합
- 효율성과 설명력을 모두 확보하는 방법
- Enum ordinal 값과 이름/설명을 매핑하는 별도 테이블 (PostStatusInfo 등)을 생성
- Post 엔티티에서 status 컬럼은 숫자로 저장, statusInfo와 다대일 연관관계로 의미까지 조회 가능
- statusInfo 테이블: id(ordinal), name, description 등
4. PostgreSQL ENUM 타입 활용 및 Hibernate 연동
- PostgreSQL은 사용자 정의 ENUM 타입을 지원
- ENUM 타입은 문자열처럼 보이지만 내부적으로 4바이트로 저장됨
- Java Enum과 PostgreSQL ENUM 매핑을 위해 Hibernate 커스텀 타입이 필요함
5. Hibernate 커스텀 타입의 필요성
- Hibernate는 다양한 내장 타입 지원을 제공하지만, 실제 현업에서는 종종 기본 타입만으로는 충분하지 않을 수 있음
- i.g. IPv4/IPv6 주소, JSON, 배열, 복합 구조 등 데이터베이스 고유 타입을 완벽하게 매핑하려면 커스텀 타입 필요
- 적절한 데이터베이스 타입을 선택하면 데이터 접근 성능이 크게 향상됨
- Hibernate는 개발자가 직접 새로운 Type을 손쉽게 추가할 수 있도록 유연한 확장 구조를 제공
5.1 IPv4 주소 저장 방식 예시
- IPv4 주소(예: 192.168.123.231/24)를 데이터베이스에 저장하는 방법은 여러 가지가 있음
- BIGINT 또는 NUMERIC(15): 4바이트(IP) + 1바이트(서브넷 마스크)를 합쳐 5바이트 정보 저장 가능하지만 비트 연산, 변환 로직이 필요해 개발 난이도가 높고, 가독성이 떨어질 수 있음
- VARCHAR(18): 사람이 읽기 쉬운 문자열(최대 18자)로 저장, 접근성과 변환은 쉽지만 공간 효율이 떨어짐
- 데이터베이스 고유 타입: PostgreSQL의 inet 혹은 cidr 타입은 네트워크 주소 전용으로 설계되어 7바이트로 저장하며,
주소 비교, 포함, 변환 등 다양한 연산자와 함수 지원- i.g. host(inet), netmask(inet), <, >, && 등
PostgreSQL inet 타입과 Hibernate 커스텀 타입 구현
- PostgreSQL의 inet 타입은 IPv4/IPv6를 효율적으로 저장할 수 있으며, 다양한 네트워크 연산을 데이터베이스 레벨에서 바로 수행할 수 있음
- Hibernate에서 PostgreSQL inet 타입을 완벽하게 활용하려면, 커스텀 타입을 직접 구현해야 함
부연 설명
- 커스텀 타입을 통해 Hibernate/JPA에서 PostgreSQL INET 컬럼과 완벽하게 매핑
- GIST 인덱스를 사용하면 네트워크 연산(<<=, >>=, && 등)도 효율적으로 실행
- JPQL/Criteria, Native Query 모두에서 커스텀 타입 안전하게 사용 가능
- 주소, 네트워크 마스크 추출 등 PostgreSQL 함수 (host(ip), netmask(ip) 등)도 활용 가능
참고
인프런 - 고성능 JPA & Hibernate (High-Performance Java Persistence)
반응형
'DB > JPA' 카테고리의 다른 글
[Hibernate/JPA] 관계 (0) | 2025.06.02 |
---|---|
[Hibernate/JPA] 식별자 생성 최적화 전략 (0) | 2025.05.30 |
[Hibernate/JPA] Connection (0) | 2025.05.29 |
[JPA] Hibernate MultipleBagFetchException (0) | 2023.06.28 |
[JPA] 준영속(Detached) 상태 엔티티 수정하는 방법 (0) | 2023.05.07 |