"0000-00-00 00:00:00" error?
이번 주 회사에서 예약 서비스를 개발하다가 발생한 문제입니다.
회사에서 mysql의 datatimes값으로 0000-00-00 00:00:00 등의 format을 많이 사용하고 있었습니다.
그런데 문제가 발생해서 이런 값 사용은 절대 지양했으면 좋겠다고 생각하게 되었는데, 이유를 말씀해드릴게요!
1. DB Error: Incorrect datetime value
MySQL 8.0의 sql_mode은 기본값으로 아래 세팅들을 포함하고 있습니다.
- ONLY_FULL_GROUP_BY
- STRICT_TRANS_TABLES
- NO_ZERO_IN_DATE
- NO_ZERO_DATE
- ERROR_FOR_DIVISION_BY_ZERO
- NO_ENGINE_SUBSITUTION
저기서 특히, NO_ZERO_IN_DATE와 NO_ZERO_DATE는 0월 0일 같이 실제로 존재하지 않는 날짜를 저장하는 것을 허용하지 않겠다는 뜻입니다.
즉, "0000-00-00", "2020-00-01" 등의 날짜를 사용할 수 없습니다.
이런 점은 sql_mode를 수정하면 해결할 수는 있습니다.
set global sql_mode = "NO_ENGINE_SUBSTITUTION";
SET session sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
하지만 저런 값을 사용하기 위해서 sql_mode를 수정해야 한다면, 나중에 실서버 DB, 개발용 DB, 테스트용 DB를 관리하기 힘들어집니다.
문제를 파악하기도 힘들 뿐더러, sql_mode를 수정하고 보니까 해당 DB 커넥션의 다른 스키마가 터질수도 있습니다. 실수로 sql_mode를 날리거나 할 위험도 커지구요.
저는 이번주에 시스템을 개발하는데, 테스트코드에서 테스트가 깨지더라구요..(Error: Incorrect datetime value) 그런데 개발서버에서 디버깅은 또 됩니다.
그래서, 테스트를 잘못 작성했겠거니..하고 2시간을 찾아도 문제가 안보이더라구요.. 알고보니까 이런 문제였습니다.
2. Code layer
문제가 한 가지 더 있습니다.
프로그래밍 언어에서 해당 데이터를 생성하지 못할 가능성이 큽니다.
Javascript를 예로 들면 아래의 코드로 Date를 생성한다고 가정하겠습니다.
new Date(0, 0, 0, 0, 0, 0);
결과는? 아래의 결과가 출력됩니다.
1899-12-31 00:00:00
이유는 Javascript에서 1900년도 이전의 Date를 생성할 수 없기 때문입니다. 이런 문제 때문에 생각했던 로직과 다르게 동작할 수 있습니다.
설령 문제를 이해했더라도, String으로 작성해야 하는데 그러면 검증을 만드는 게 상당히 복잡해지죠.
결론
그래서 저런 양식은 사용하지 않는게 유지보수 측면에서 월등히 좋습니다.
가령, 시간을 저장한다면 0000-00-00 00:00:00 ~ 0000-00-00 02:00:00이 아니라, mysql의 time을 사용해서 HH:MM:SS ~ HH:MM:SS 을 사용한다던지, int나 varchar로 해결하는 것이 좋습니다.
그리고 datetime에서 초기를 의미해야한다면 차라리 null ~ 2022-02-20 처럼 저장하는 것이 바람직합니다.
감사합니다.
'Database > SQL' 카테고리의 다른 글
MySQL - 쿼리 성능(실행 시간, CPU 사용량 등) 확인하는 방법 [Profiling] (0) | 2022.03.20 |
---|---|
SQL 튜닝 - SELECT 절과 WHERE 절에 동일한 함수가 사용될 때 [성능 비교] (0) | 2022.03.17 |
SQL - 트랜잭션 범위 개선 (0) | 2022.02.13 |
MySQL - 슬로우 쿼리 로그 설정 (자동으로 느린 쿼리 로그 남기기) (0) | 2022.02.06 |
Real MySQL - MySQL 기본 구조(+ 쿼리 실행 과정, 메모리 할당 구조, ...) (0) | 2022.02.05 |