Study/Backend

char 와 varchar 비교

david95j2 2020. 11. 19. 22:31

CHAR

  • CHAR는 고정 사이즈이다.

  • 남는 공간은 공백으로 채우게 된다.

  • 공백 채움 비교(blank-padded comparison semantics)를 사용한다.

  • 예를 들어 CHAR(10) 인데 ‘test’라는 4자짜리 문자열을 insert하게 되면 남는 공간은 6개의 공백으로 채우게 된다.

  • 따라서 무조건 처음 선언된 10byte가 소요된다.

  • 물론 값을 받아 올 때 이 공백은 자동으로 제거된다.
    공백까지 읽고 싶다면 PAD_CHAR_TO_FULL_LENGTH 모드를 활성화하면 공백까지 다 읽어온다.

  • CHAR형의 경우 삽입되는 데이터가 선언된 길이보다 작다면
    남는 공간은 스페이스로 채워지므로 공간의 낭비가 발생한다.

  • 따라서 반드시 고정길이에 해당하는 데이터만 CHAR로 선언하시는 것이 좋다.


VARCHAR

  • VARCHAR는 이름이 의미하듯 가변길이이다.

  • 데이터를 삽입하면 데이터값외에 삽입된 문자열의 길이를 저장하는데
    255글자 이하에는 1바이트, 그 이상은 2바이트의 추가 공간을 필요로 한다.

  • 즉 실질적인 데이터와 길이 정보도 같이 저장된다.

  • 예를 들어 VARCHAR(10)에 ‘test’라는 4자짜리 문자열을 삽입하면
    4byte + 1byte(길이를 저장하기 위한 메모리) = 5byte가 소모된다.

  • 저정할 수 있는 길이는 0부터 255까지이며
    MySQL 5.0.3 이후에는 0부터 65,535까지 지정할 수 있다.

 

  • VARCHAR 값은 저장될 때에 공백이 추가되지 않는다.

  • 하지만 공백에 대한 처리는 버전에 따라 다르다.

  • MySQL 5.0.3 이후부터는 표준 SQL과의 호환성을 위해 뒤따르는 공백들을 제거하지 않고 보관하며 읽어들일 때도 보존해준다.

  • MySQL 5.0.3 이전에는 저장될 때에 뒤따르는 공백들은 제거되었고 이는 값을 읽어들일 때에도 제거된 채로 읽힘을 의미한다.

  • MySQL 5.0.3 이전에 뒤따르는 공백들을 유지하기 위해서는 BLOB나 TEXT 형을 선택해야 했다.

 

  • 기존 데이터 길이보다 더 큰 데이터로 업데이트할 경우 데이터 파편화가 발생한다.

  • 기존 보다 큰 데이터를 저장하기 위해서 새로운 저장 영역에 새로 할당해야하므로 데이터 파편화가 발생한다.

  • 테이블 ROW 중에 CHAR, VARCHAR 타입이 섞여 있으면 데이터 파편화는 발생할 수 밖에 없다.

  • 파편화를 염두하고 설계한다면 테이블의 데이터 타입 중에 VARCHAR 타입을 사용해선 안된다.

  • 그러나 MySQL에서는 다음의 쿼리를 적용하면 파편화를 막을 수 있다.

ALTER TABLE tblname ROW_FORMAT = FIXED;

  • VARCHAR 타입을 CHAR 타입처럼 동작하도록 강제로 지정하는 것이다.

  • CHAR처럼 동작하기 때문에 데이터 용량은 증가하지만

  • VARCHAR로 인한 파편화로 성능 저하는 막을 수 있다.

 

  • 특이한 점으로는 4자 이하의 VARCHAR는 CHAR로 자동 변환된다.

  • 만약 테이블안에 VARCHAR나 text, blob 같은 가변길이 데이터가 하나라도 있을 경우
    3자 이상의 CHAR컬럼이 자동으로 VARCHAR로 바뀌게 된다.

  • TABLE을 만든 후 실제로 무슨 형으로 변환되었는지 DESC table_name으로 확인 할 수 있다.

  • 이렇게 하는 이유는 물론 성능과 속도 때문이다.

Q. 그렇다면 모두 VARCHAR를 사용하지 않는 이유는 무엇일까?

  • 무조건 VARCHAR를 사용시 가변이기 때문에
    내부에서 추가적인 Logic이 발생되어 속도 저하를 일으킬 수 있다.

CHAR와 VARCHAR의 비교

저장 영역

  1. CHAR형은 고정형. 최대 길이는 255.

  2. VARCHAR형은 가변형. 최대 길이는 255,
    MySQL 5.0.3 이후부터는 65,535까지 가능.

  3. MySQL 4.1 이후 버전부터는 CHAR(n), VARCHAR(n)에서 n은 바이트가 아니라 글자 수를 의미한다.
    ex) CHAR(30)은 30 글자까지 보관할 수 있다.

  • VARCHAR 유형은 가변 길이이므로 필요한 영역은 실제 데이터 크기뿐이다.

  • 그렇기 때문에 길이가 다양한 컬럼과 정의된 길이와 실제 데이터 길이에 차이가 있는 컬럼에 적합하다.

  • 저장 측면에서도 CHAR 유형보다 작은 영역에 저장할 수 있으므로 장점이 있다.


비교 방법

  • CHAR에서는 문자열을 비교할 때 공백을 채워서 비교하는 방법을 사용한다.

  • CHAR(8)이고 ‘AA’가 저장되어 있다면 ‘AA’ 뒤에 공백 6자리를 붙여 8자리로 비교하는 것이다.

따라서 'AA' = 'AA '은 실제로 'AA ' = 'AA '가 되어 같다는 결과가 나온다.

  • 반면 VARCHAR에서는 공백도 하나의 문자로 취급하므로 끝에 공백이 들어가면 다른 문자로 판단한다.

같은 예로 들면 'AA' != 'AA '로 공백이 있어 서로 다른 문자로 판단한다.

  • 따라서 이름, 주소 등의 길이가 변할 수 있는 값은 VARCHAR를 사용하고

  • 사번, 주민등록번호와 같이 길이가 일정한 데이터는 CHAR를 사용하는게 좋다.

'Study > Backend' 카테고리의 다른 글

Synchronous / Asynchronous  (0) 2020.11.30
[mysql] 날짜 형식  (0) 2020.11.23
java 포맷형식 출력  (0) 2020.11.18
JDBC 문제?  (0) 2020.11.15
JDBC란  (0) 2020.11.14