TIL/Database

[MySQL] INT(11)과 DATETIME(6)의 비밀

oraange 2023. 4. 11. 13:02

11자리 숫자까지?

django orm을 사용하여 Table을 생성하고(migration) 관리하기만 하다가 문득 저 괄호 안의 숫자의 의미가 궁금해졌다.

bigint(20)같은 경우에 20자리 숫자까지 표현하는데 20자리가 넘어가면 에러가 나거나 문제가 생기는 것이 아니다.
해당 필드에 ZeroFill(ZF) 옵션이 체크가 되어있을 경우 20자리까지 0을 채워 넣는다는 얘기이다.

예를 들면, 위 사진에서 font_size 필드가 smallint(5)인데, ZF가 true일 경우, 12라는 숫자를 넣게되면 00012라는 값으로 들어온다.
즉, ZF옵션이 체크되어 있을 경우에만 유의미하고 그렇지 않은 경우에는 상관없다. 그러나 각 type에 맞게 범위가 들어와야한다. smallint의 경우 -32768 부터 32767 까지의 숫자만 들어올 수 있으므로 범위를 벗어나는 숫자는 에러가 날 것이다.

그러나 smallint(3)인 필드에 32766을 넣어도 에러가 나지 않는다. 단지 integer type의 (N)은 부가적인 정보라고 생각하면 된다(ZF이 체크되어있을 경우에만)

DATETIME(6)

Datetime type의 경우에는 괄호 안의 숫자가 어떤 의미일까? 이것은 바로 초단위 아래 소수점이 6자리까지 표현한다는 얘기이다.

다음과 같이 초단위 뒤에 7자리 숫자를 넣고 수정을 해보았다. 결과는

초단위 뒤에 123457이라는 숫자로 바뀌었다. 그 이유는 DATETIME(6)이므로 소수점 뒤에 6자리 숫자까지만 표시하는데 7번째 자리에서 반올림을 하기 때문이다. 즉, 1234561이라는 숫자를 넣으면 123456까지만 표기된다. 하지만 이 경우 문제점이 발생하는데,

다음과 같이 1월 31일 오후 11시 59분 59.999999초 같은 경우이다. 만약 초가 59.9999996일 경우에 

날짜가 다음 날로 넘어간다. 이렇게 되면 특정 날, 특정 월, 심지어는 특정 해까지 데이터를 Grouping할 때 문제가 생길 수도 있다.

예를 들면, 12시 자정이 기한인 과제를 다 하고 서버에 업로드를 할 때 DB에 해당 과제의 업로드 시간과 과제물이 write된다고 하자. 그런데 `23:59:59.6` 이 시간에 올린 학생의 과제물은 분명 자정 전에 업로드를 완료했지만 DB상에는 다음 날로 기록이 될 것이다. 물론 0.5초를 남기고 과제물을 낼 경우는 희박하겠지만 이런 억울한 불상사를 막기 위해서 구조를 잘 짜야 할 것 같다.

반응형