년월일의 날짜정보를 저장할 때 varchar(8)
을 이용하여 표현하는 것을 종종 볼 수 있는데요.
MySQL의 date
타입을 이용하면 더욱 효율적으로 정보를 저장하고 조회할 수 있어 이에 대해 공유 드리고자 합니다.
date
타입은 'YYYY-MM-DD' 형식의 날짜 타입입니다. 시간을 저장하지 않습니다.
먼저 표를 통해 간략한 차이점을 알아보겠습니다.
varchar(8) | date | |
---|---|---|
size | 9byte | 3byte |
validation | X | △ |
타 언어와 호환 | X | O |
비교 및 연산 | △ | O |
가독성 | 낮음 | 높음 |
아래에서 하나씩 살펴보겠습니다.
1. size
varchar(8)
사용 시 언뜻 하이픈(-) 없이 데이터를 압축, 저장할 수 있을 것만 같지만 실제로는 date
타입에 비해 3배 큰 용량을 차지하게 됩니다.
MySQL에서 varchar는 String
데이타 타입 중 하나로 가변(variable) 문자(character) 타입을 의미합니다. 고정된 용량을 사용하는 char
와 달리 varchar
는 실제 용량을 표현하기 위한 prefix를 필요로 합니다.
따라서 varchar(255)
이하에서는 1 byte, 이상에서는 2 byte의 용량이 필요합니다. (1 byte = 8 bit, 즉 2^8=256, 0부터 255까지)
UTF-8 인코딩방식에서는 하나의 문자 당 1바이트에서 최대 4바이트를 지원하지만 우리가 사용할 숫자로만 구성된 년월일의 경우 각 1바이트 * 8에 prefix인 1byte까지 총 9 byte를 필요로 합니다.
반면 date
타입은 '1000-01-01' 부터 '9999-12-31' 까지의 값을 지원하며 3 byte의 용량을 필요로 합니다. 년, 월, 일을 나누어 인식하므로 최대 값('9999-12-31')도 3 byte로 충분히 표현할 수 있습니다.
2. validation
값 입력 시 varchar(8)
문자열은 각 문자열을 년, 월, 일로 잘라 각각이 유효한 값인지 검사하여야 하지만 실제 저희 프로그램에서는 자리 수 체크 정도만 진행되고 있습니다. '88888888'도 유효한 날짜로 인식됩니다.
date
타입은 날짜 타입인 만큼 월과 년,월에 따른 일에 대해 유효하지 않은 경우 예외가 발생합니다. 예를 들어 '1990-02-29' 또는 '2000-11-31' 같은 값은 입력할 수 없습니다.
그러나 모든 유효하지 않은 날짜를 막는 것은 아닙니다(00월이나 00일은 허용). 또 비즈니스마다 유효한 연도의 범위도 필요하므로 이 이상의 validation은 어플리케이션 단에서 로직을 통해 통제하는 것이 합리적으로 보입니다.
3. 타 언어와 호환
MySQL date
타입은 java.sql.Date
로 리턴됩니다. 또 java.lang.String
, java.sql.Date
, java.sql.Timestamp
와 같은 객체로 변환이 가능합니다.
즉 라이브러리에서 지원되는 연산이나 비교 등의 작업이 가능하다는 얘기입니다.
String
타입으로 받더라도 저희 프로그램에서 사용하는 java와 javascript에서 날짜를 표현하는 객체는 'YYYY-MM-DD' 포맷의 문자열로 객체 생성 및 초기화가 가능합니다.
java 예시
LocalDate date = LocalDate.parse("2022-01-13");
javascript 예시
Date = new Date("2022-01-13");
비즈니스 로직에서 validation, 날짜 연산 등을 위해 객체를 이용해야 할 경우가 많습니다. date
타입의 경우 DB에서 조회한 문자열 그대로 별도의 가공 없이 사용할 수 있습니다. 생산성과 코드 가독성이 향상됩니다.
java 로직 예시
try{
LocalDate date = LocalDate.parse("2022-00-00"); //DateTimeParseException 발생
}catch(DateTimeParseException e){
//...예외 처리 내용
}
반면 varchar
를 이용한다면 문자열을 자른 후 각각 별도의 로직 구현을 통해 연산 및 계산하거나, 문자열을 다시 객체로 만들 수 있도록 별도의 가공을 해야합니다.
4. 비교 및 연산
MySQL에서는 날짜 연산을 위해 자체적으로 다양한 함수들을 제공합니다 MYSQL 날짜 및 시간 함수.
date
타입은 datetime
, timestamp
등의 날짜 타입과 호환되므로 위 링크의 모든 함수 사용이 가능합니다.
varchar(8)
의 경우 String
타입이므로 바로 함수를 사용할 수 없습니다. DATE() 함수나 STR_TO_DATE() 함수로 가공 후 사용해야 합니다. 단순 문자열 비교는 가능하지만 더 구체적인 월 비교, 일 비교나 더 나아가 연산은 지원되지 않습니다.
5. 가독성
YYYY-MM-DD는 일반적으로 년, 월, 일을 인식하는 포맷입니다.
현재 사용자가 보는 화면 또한 가독성을 위해 포맷팅 작업을 일일이 별도로 해주고 있는데 date
를 사용하면 문자열 그대로 받아 사용하면 됩니다.
위처럼 별도의 포맷팅이 없어도 아래와 같이 표현됩니다.
사용자와 개발자 모두에게 가독성과 편의성을 향상시켜줍니다.