ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JPA] 긴 길이의 문자열 저장하기
    Programming/JPA 2021. 6. 20. 22:59

    개요

    프로젝트를 진행하던 중 프론트에서 특정한 블로그의 게시글 내용을 markdown 문법을 기반으로 긴 길이의 문자열을 전송하여 백엔드와 연동된 DB인 MySQL에 저장하도록 정하게 되었다. JPA에서 긴 길이의 가변 문자열을 처리하는 방법에 대해 알아 보았고 다양한 테스트를 거쳐 각각의 차이를 확인해보았다.


    SQL 데이터형

    CHAR 

    고정 사이즈이고 남은 공간은 공백으로 채운다. 삽입되는 데이터가 선언된 길이보다 작다면 공간의 낭비가 우려된다. 주민등록번호와 같이 고정된 길이의 데이터는 CHAR를 사용하는 것이 더욱 좋을 것이라고 생각된다.

     

    VARCHAR

    가변 길이이다. 데이터를 삽입하면 데이터 값 외에 삽입된 문자열의 길이를 저장한다. 255글자 이하에는 1바이트를 필요로 하고, 그 이상은 2바이트의 추가 공간을 필요로 한다. 최대 길이는 65535이다. 하지만 MySql의 버전에 따라 처리하는 방식이 다르다고 한다. 관련 내용은 좀 더 보충이 필요하다.


    JPA에 적용

    @Column(length = 50000)
    private String content;

    @Column 애노테이션을 활용하여 DDL이 실행되는 시점에 varchar의 길이를 50000으로 제한한다. 

     

    현재 application.yml에 ddl-auto는 create-drop으로 설정해두었기 때문에 서버가 구동되는 시점에 새롭게 create 된다. 아래를 살펴보면 varchar(50000)으로 create를 진행하는 것을 알 수 있다.

    2021-06-20 22:10:02.602 DEBUG 19356 --- [  restartedMain] org.hibernate.SQL                        : 
        
        create table posts (
           posts_id bigint not null auto_increment,
            created_date datetime(6),
            last_modified_date datetime(6),
            content varchar(50000),
            delete_status bit,
            title varchar(255),
            view integer,
            blog_id bigint,
            category_id bigint,
            primary key (posts_id)
        ) engine=InnoDB

     

    50000 길이의 content를 저장하는 간단한 테스트이다. 

    @Test
    @DisplayName("최대 길이의 content를 저장하는 테스트")
    void test() {
    
        // given
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 50000; i++) {
            stringBuilder.append("+");
        }
    
        Posts posts = Posts.builder()
                .blog(blog)
                .title("게시글")
                .content(stringBuilder.toString())
                .category(category1)
                .build();
    
        Posts save = postsRepository.save(posts);
    
        // when
        Posts findPosts = postsRepository.findById(save.getId()).get();
    
        // then
        assertEquals(findPosts.getContent().length(), 50000);
    }

    정상적으로 처리되는 것을 확인하였다. 하지만 @Column의 경우 spring.jpa.hibernate.ddl-auto 옵션이 create-drop이거나 create인 경우에만 해당 애노테이션의 속성들이 자동적으로 적용될 것이다. 하지만 운영을 위한 DB에는 해당 옵션을 적용하는 것은 위험하기 때문에 ddl script를 따로 작성해주는 것이 바람직하다.


    정리 및 느낀점

    표면상으로 보면 단순히 50000개의 글자수 만큼 저장할 수 있도록 수정하였다. 하지만 아직 DB에 대한 학습이 부족하여 내부적으로는 어떤식으로 큰 길이의 문자열이 처리되는지 모르기 때문에 어떠한 문제점을 가져올지 예측할 수 없다. 

     

    DB에 대한 지식이 부족함을 느꼈고, 각각의 버전과 DBMS의 종류에 따라 데이터를 처리하는 방법도 달랐다. 모두 알 순 없지만 자주사용하는 DB에 대해서는 정리가 필요하다고 느끼는 계기가 되었다.


    Reference

     

    DB 컬럼(Column) 타입 차이 알아보기 : CHAR vs VARCHAR 비교 및 특징

    Index

    goodgid.github.io

     

    댓글

Designed by Tistory.