sql >> Base de Datos >  >> RDS >> Mysql

Convertir valores negativos de FROM_UNIXTIME

Podemos hacer esto en su lugar:

FROM_UNIXTIME(0) + INTERVAL -957632400 SECOND

El FROM_UNIXTIME la función está limitada por el rango permitido para el TIMESTAMP tipo de datos, que es el rango int estándar de 32 bits sin firmar desde 1970-01-01 hasta 2038-01-algo. Se ha actualizado otro software para admitir enteros con signo de 64 bits, pero MySQL aún no proporciona esa funcionalidad (al menos no en 5.1.x).

La solución alternativa en MySQL es evitar el uso de TIMESTAMP tipo de datos y usando el DATETIME en su lugar, cuando necesitamos un rango mayor (por ejemplo, fechas anteriores al 1 de enero de 1970).

Podemos usar el DATE_ADD función para restar segundos del 1 de enero de 1970, así:

SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)

N.B. Probablemente necesitará tener en cuenta las "desviaciones" de la zona horaria de UTC al hacer ese tipo de cálculos. MySQL va a interpretar los valores DATETIME como especificados en time_zone configuración de la sesión MySQL actual, en lugar de UTC (time_zone = '+00:00' )

SEGUIMIENTO:

P: Bien, significa que si seleccionamos fechas por debajo de '1970-01-01 00:00:00', el valor negativo se guarda en la base de datos; de lo contrario, sería positivo. ¿Derecha? – génico suave

R: Uhhh, no. Si selecciona valores de fecha/fechahora antes del 1 de enero de 1970, MySQL devolverá valores de FECHA o FECHAHORA antes del 1 de enero de 1970. Si almacena valores de FECHA o FECHAHORA antes del 1 de enero de 1970, MySQL almacenará valores de FECHA o FECHAHORA antes del 1 de enero , 1970, dentro del rango permitido admitido por esos tipos de datos. (algo así como 0001-01-01 a 9999?)

Si necesita almacenar números enteros positivos y negativos realmente grandes en la base de datos, probablemente los almacene en una columna definida como BIGINT .

La representación interna de una columna DATE requiere 3 bytes de almacenamiento, y DATETIME requiere 8 bytes de almacenamiento (hasta la versión 5.6.4 de MySQL. La representación interna y el almacenamiento de los valores DATE y DATETIME cambiaron en 5.6.4)

Así que no, MySQL no almacena valores de fecha anteriores a 1970 como "enteros negativos".

Si lo piensa un poco, MySQL es libre de implementar cualquier mecanismo de almacenamiento que desee. (Y cada motor de almacenamiento es libre de serializar esa representación en el disco como quiera).

¿Por qué 3 bytes para una fecha?

Una opción que tiene MySQL (y no pretendo decir que así es como se hace) podría ser dividir la fecha en sus componentes año, mes y día.

La representación de valores enteros en el rango - requiere -

  • 0 - 9999 - 14 bits

  • 0 - 12 - 4 bits

  • 0 - 31 - 5 bits

Eso es un total de 23 bits, lo que resulta que cabe fácilmente en 3 bytes. Esto solo demuestra que no es necesario que MySQL represente valores de fecha anteriores al 1 de enero de 1970 como enteros negativos, por lo que no debemos suponer que lo hace. (Pero realmente solo nos preocuparíamos por este nivel de detalle si estuviéramos trabajando en un motor de almacenamiento para MySQL).