MySQL에서 날짜와 시간 정보를 저장하기 위한 여러가지 데이터 타입이 있다.
그 중에서 날짜와 시간을 합쳐서 하나의 칼럼에 저장할 수 있는 데이터 타입은 DATETIME과 TIMESTAMP이다.
DATETIME과 TIMESTAMP의 차이점과 각각의 장단점을 알아보기 위해, 날짜와 시간 타입에서 발생할 수 있는 2가지 문제를 중심으로 살펴보려고 한다. 바로 타임존 문제와 Y2K38 문제이다.
타임존(timezone) 문제
타임존은 지구 상의 서로 다른 지역의 시차로 인해 온라인 상에서 시간의 불일치가 발생하는 것을 해결하기 위한 수단이다.
타임존을 표현할 때는 UTC 시간을 기준으로 하며, 한국 시간의 경우 UTC+09:00 시간대로 표현된다. UTC+00:00 타임존으로 표현된 시간 값을 한국에서 표시할때는 오프셋인 9시간을 더해서 표시함으로써 시간 불일치를 해소할 수 있다.
TIMESTAMP 타입은 타임존을 고려하여 저장되며, 데이터베이스 서버에 설정된 타임존에 관계 없이 기본적으로 UTC+00:00 값으로 저장된다.
한편 DATETIME 타입은 타임존이 반영되지 않은 값으로 저장되며, 서버 시간대를 기준으로 저장된다. 즉 한국 시간대로 저장해도 데이터베이스 서버 시간대가 UTC+00:00이라면 한국 시간에서 9시간 이전의 값으로 저장된다.
따라서 시간대에 대한 혼선을 방지하기 위해서는 절대적인 UTC 시간대를 고려하여 데이터를 저장하는 TIMESTAMP 타입이 더 유리하다고 볼 수 있다.
Y2K38 문제
Y2K38 문제는 Year 2038 Problem, 즉 2038년에 발생되는 날짜 시간과 관련된 문제이다.
TIMESTAMP는 유닉스 시간 또는 Epoch 시간으로 불리는데, 1970년 1월 1일 자정을 기준으로 경과 시간을 초(second) 단위로 환산하여 정수로 표현한다. 4바이트의 정수로 표기하며, 따라서 1970년 1월 1일 자정을 기준으로 2^32 초 이후까지만 표현할 수 있다. 이 날짜가 2023년 1월 19일 3시 14분 7초이다.
따라서 TIMESTAMP 타입은 1970-01-01 00:00:00 부터 2038-01-19 03:14:07까지 지원한다.
반면 DATETIME 타입은 1000-01-01 00:00:00부터 9999-12-31 23:59:59까지 표현 가능하므로 TIMESTAMP보다 더 넓은 범위를 지원한다.
DATETIME vs. TIMESTAMP, 어떻게 저장해야할까?
DATETIME을 사용하는 경우에는 다양한 타임존을 커버하려면 데이터베이스에 데이터를 삽입하는 과정에서 입력 값의 타임존을 일관되게 만들어주는 로직이 필요하다.
데이터베이스에 날짜와 시간을 저장할 때 created_at과 같이 데이터베이스에서 자동으로 생성되는 값은 데이터베이스의 타임존에 따라 일관되게 저장될 것이므로 문제되지 않을 것이다.
그러나 클라이언트 측에서 전달한 시간 값을 저장해야할 때는 클라이언트의 타임존을 고려하여 입력 값을 변환해야한다. 예를 들어 한국 시간 '2024-03-01 09:00:00'을 문자열로 전달하여 그대로 데이터베이스에 저장하게 되면 데이터베이스의 타임존인 UTC+00:00 기준의 '2024-03-01 09:00:00'을 저장하게 된다. 이 레코드를 다시 한국 시간대로 조회하면 9시간을 더 더한 값인 '2024-03-01 18:00:00'가 되어, 클라이언트에서 처음에 전달했던 시간과 9시간이 차이나게 된다.
따라서 데이터베이스에 접근하는 애플리케이션 계층에서 타임존 처리를 위한 로직을 만들어 관리해줘야한다. 입력된 시간을 UTC 시간으로 변환하여 데이터베이스에 전달하는 것이 한가지 방법이 될 수 있다.
TIMESTAMP는 클라이언트의 타임존이 반영되어 데이터베이스에 UTC 값으로 저장된다는 전제 하에 별도의 타임존 변환 로직을 구현할 필요는 없다. 다만 이 경우에도 클라이언트의 시간대가 제대로 반영이 되는지 주의해야한다. 예를 들어 어느 지역에서 접속하는지와 관계 없이 데이터베이스에 접근하는 백엔드 서버의 타임존이 하나로 고정되어 있다면 실제 요청을 보낸 클라이언트의 타임존을 반영한 시간 정보로 변환하는 로직이 필요할 것이다.
결론적으로, 데이터베이스에 저장할 때 어떤 데이터 타입을 사용하는지 보다는 데이터베이스에 일관된 타임존으로 저장하는 것이 중요한 것 같다. 또한, 클라이언트의 타임존을 고려하여 변환된 시간을 표시하는 것은 프레젠테이션 계층에서 담당하여 데이터베이스 단에서는 타임존 변환과 관련된 복잡한 로직을 처리하지 않도록 하는 것이 바람직할 것 같다.
'데이터베이스 > MySQL' 카테고리의 다른 글
[MySQL] InnoDB 클러스터 (0) | 2024.03.29 |
---|---|
[MySQL] 데이터베이스 복제(Replication) (0) | 2024.03.21 |
[MySQL] 파티셔닝 종류 정리 (0) | 2024.03.08 |
[MySQL] 온라인 DDL (2) | 2024.03.01 |
[MySQL] 지연된 조인(Delayed Join) (0) | 2024.02.23 |