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를 찾아보니, char 및 varchar 타입은 최대 문자 수를 나타내는 길이로 선언되는데, 예를 들어 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 |