본문 바로가기

DB

[DB] 문자열 데이터 타입에 글자(한글) 수 제한하기

create table post(
              ...
    title varchar(30) not null
              ...
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

DB(MySQL)에 게시글을 저장하는 기능을 구현하면서, post 테이블을 생성하였다.

게시글을 저장할 때의 요구 사항은 제목의 최대 글자는 10자였고, utf-8 버전의 한글은 3byte를 차지하므로 데이터 타입을 varchar(30)으로 정의하였다.

💬 UTF-8

UTF-8은 유니코드 문자를 인코딩하는 가변 길이 문자 인코딩 방식 중 하나로, 8비트 기반의 문자 인코딩 방식이다.

ASCII 문자(영어...)는 1byte로 표현하고, 한글과 같은 유니코드 문자는 3바이트로 표현한다. 

 

insert into post(title) values('테스트테스트테스트트트'); # 11글자

 

하지만, 막상 11글자의 제목을 저장하니 정상으로 완료되었다.


 

위 이슈에 대해 MySQL Reference를 찾아보니, charvarchar 타입은 최대 문자 수를 나타내는 길이로 선언되는데, 예를 들어 varchar(10)은 10byte가 아닌 최대 10자까지 입력할 수 있다는 의미이다.

즉, 위에서 varchar(30)으로 데이터 타입을 정의했기 때문에, 10자가 아닌 30자까지 저장할 수 있었던 것이다.

 

create table post(
              ...
    title varchar(10) not null
              ...
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

이번에는 varchar(10)으로 데이터 타입을 정의했다.

 

insert into post(title) values('테스트테스트테스트트트'); # 11자
insert into post(title) values('abcdefhhijk'); # 11자

varchar(10)으로 정의하니 제목에 11자의 데이터를 입력하면 Data too long for column 'title' 오류가 발생하는 것을 확인할 수 있다.


create table post(
    title varchar2(10) not null
);

이번에는, Orcale DB에서도 MySQL DB 환경에서와 마찬가지로 varchar2(10) 타입이 10byte가 아닌 10자인지 확인해 보기 위해 같은 조건으로 테이블을 생성하였다.

 

insert into post(title) values('테스트테스트테스트트트'); # 11자

11자의 제목을 저장하려고 하니 title 컬럼에 대한 값이 너무 크다는 에러가 발생하였다.


이번 이슈에 대한 답 역시 Oracle Reference에서 확인할 수 있었다. Oracle DB에서 varchar2(size) 데이터 타입의 size는 1 byte를 의미한다. 따라서, varchar2(10)은 최대 10자가 아닌 최대 10byte로 '테스트테스트테스트트트'는 utf-8 환경에서 33byte로 에러가 발생하는 것이다.

 

insert into post(title) values('테스트'); # 3자

'테스트' 총 9byte의 데이터를 저장하니 정상적으로 저장되는 것을 확인할 수 있다.

 

📝 결론

MySQL 환경에서 varchar(size)를 사용한다면, 이때의 size는 글자 수이고, Oracle 환경에서 varchar2(size)를 사용한다면, 이때의 size는 byte 수이므로 잘 고려해서 데이터 타입을 정의하자

'DB' 카테고리의 다른 글

[DB] 정규화  (0) 2022.12.15
[DB] MySQL  (0) 2022.12.08
[DB] MySQL vs PostgreSQL  (0) 2022.11.19
Hot Key  (0) 2022.11.09