Real my sql -1. CHAR /VARCHAR /TEXT

Alex·2024년 7월 1일
0

리팩토링

목록 보기
1/17

인프런의 Real my sql 강의를 참고하면서 프로젝트를 리팩토링한다.

우선, 이 타입들을 사용하면 문자열을 저장할 수 있게 된다.
CHAR는 고정형, VARCHAR는 가변형, TEXT는 최대 65,535 바이트까지 저장할 수 있다.

그럼 특징들을 하나씩 살펴보자.

CHAR은 최대 저장길이가 255이며 저장되는 문자열 길이에 관계없이 처음에 설정한 만큼만 공간이 할당된다. VARCHAR는 저장되는 무자열 길이만큼 공간이 할당된다.

CHAR 타입의 공간 낭비

일반적으로 고정된 길이의 값을 저장할 떄는 CHAR타입을, 그 외의 경우는 VARCHAR타입을 쓴다.

주민등록번호를 저장한다고 해보자. 이 경우에는 CHAR(13)을 써도 괜찮다. VARCHAR을 써도 큰 차이는 없다고 한다.

그런데, CHAR을 쓸 때 공간을 미리 설정해둠으로써 공간의 낭비가 발생하는 경우가 있다.

저장되는 문자열의 최소 최대 길이 가변 폭이 큰 경우

그니까, 어느 때는 긴 문자열이 저장되고 다른 때는 짧은 문자열이 저장되면 CHAR 타입에서는 공간이 낭비되는 것이다.


다만, 그렇다고 해서 항상 VARCHAR를 쓰는 것은 아니라고 한다.

VARCHAR(10)을 설정해둔 곳에 문자열을 저장한다고 해보자. 그리고, 문자열 길이가 10에서 12로 늘어났다. 이 경우에는 기존 데이터를 delete marking을 해두고(바로 지우지 않는다) 그 옆에 새로운 공간에 데이터를 저장한다.

즉, 데이터를 업데이트할 때마다 옆에 있는 빈공간을 계속 새로 찾아야 하는 것이다. 나중에 DB에서 이렇게 delete marking을 해놓은 곳을 정리할 수는 있지만, 이런 것들이 성능에 영향을 준다고 한다.

그래서, 저장되는 문자열의 가변 길이 폭이 좁고 자주 변경되는 칼럼은 CHAR를 사용할 때 데이터 변경 시 데이터 페이지 관리 작업을 최소화할 수 있다.

CHAR의 경우에는 예약 공간이 있으니까 그 공간에 데이터를 추가로 넣으면 되기 때문!


지금 프로젝트에서는 jpa를 쓸 때 문자열의 타입을 특정하지는 않았다.

public class Accommodation {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false)
    private String name;
    @Column(nullable = false)
    private int price;
    @Column(nullable = false)
    private String address;
    @Column(nullable = false)
    private int maxCapacity;
    @Column(nullable = false)
    private int roomCount;
    @Column(nullable = false)
    private int bedCount;
    @Column(nullable = false)
    private String description;
    @Column(nullable = false)
    private String amenity;
    private boolean isOnSale;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "host_id")
    private Host host;

이렇게 돼 있는데 기본으로
VARCHAR(255)으로 설정되는 듯하다.

우선, 성격으로 분류를 해보면 description과 amentiy는 가변성이 심하다. 누군가는 길게 쓸 수도 있고, 누군가는 짧게 쓸 수도 있다.

name은 VARCHAR(255)를 사용하는 것은 비효율적이지 않을까 했는데, VARCHAR는 실제 문자열만큼만 데이터를 할당한다고 하니 이대로 두어도 괜찮을 거 같다. 도로명 주소도 가변성이 심하기에 VARCHAR로 해도 괜찮다고 생각한다.

유저의 경우 name은 CHAR(4)로 해두는 것이 좋고, VARCHAR을 해도 좋겠다. 이름은 거의 변경이 없을테니 큰 차이는 없을 것으로 보인다.

jpa에서 char 타입을 쓸 때는 아래와같이 하면 된다.

@Column(columnDefinition = "CHAR(10)")
String name;

TEXT

  • VARCHAR 타입은 지정된 글자 수 만큼 데이터를 저장한다면, TEXT는 제한없이 사용가능하다.
  • 일반적으로 길이가 짧으면 VARCHAR 타입을, 길이가 길면 TEXT타이블 쓴다.

다만, 여기서 더 중요한 것은 버퍼 공간을 어떻게 활용하는가? 이다.

VARCHAR타입은 데이터를 읽을 때 메모리 버퍼 공간을 미리 할당해두고 이를 재사용한다. 버퍼공간은 테이블 레코드의 최대 사이즈로 할당된다. TEXT 타입은 그때 그때 필요할 때마다 버퍼를 할당하고 해제한다.

버퍼를 재활용해서 사용한다면 좀더 빠르게 데이터를 읽을 수 있을 것이다.

profile
답을 찾기 위해서 노력하는 사람

0개의 댓글