Database/SQL

MySQL - datetime("0000-00-00") 사용하면 안되는 이유! (+ 에러 임시 해결)

JaeHoney 2022. 2. 20. 14:09

"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 처럼 저장하는 것이 바람직합니다.

 

감사합니다.