Mysql
 sql >> Database >  >> RDS >> Mysql

DECIMAL lunghezza per microtime (true)?

tl; dott. Usa microtime(false) e memorizza i risultati in un bigint MySQL come milionesimi di secondo. Altrimenti devi imparare tutto sull'aritmetica in virgola mobile, che è un grosso bolo di pelo.

La funzione PHP microtime acquisisce il timestamp Unix (attualmente circa esadecimale 50eb7c00 o decimale 1.357.609.984) da una chiamata di sistema e il tempo di microsecondi da un'altra chiamata di sistema. Quindi li trasforma in una stringa di caratteri. Quindi, se lo chiami con (true), converte quel numero in un numero in virgola mobile IEEE 745 a 64 bit, una cosa che PHP chiama un float .

Ad oggi sono necessarie dieci cifre decimali a sinistra del punto decimale per memorizzare un timestamp UNIX intero. Ciò rimarrà vero fino al 2280 d.C. circa, quando i tuoi discendenti inizieranno ad aver bisogno di undici cifre. Avrai bisogno di sei cifre a destra della cifra decimale per memorizzare i microsecondi.

Non otterrai una precisione totale di microsecondi. La maggior parte dei sistemi mantiene il proprio clock di sistema inferiore al secondo con una risoluzione compresa tra 1 e 33 millisecondi. Dipende dal sistema.

MySQL versione 5.6.4 e successive consentono di specificare DATETIME(6) colonne, che conterranno date e orari con una risoluzione di microsecondi. Se stai usando una tale versione di MySQL, questa è assolutamente la strada da percorrere.

Prima della versione 5.6.4, è necessario utilizzare MySQL DOUBLE (IEEE 754 in virgola mobile a 64 bit) per memorizzare questi numeri. MySQL FLOAT (IEEE 754 in virgola mobile a 32 bit) non ha abbastanza bit nella sua mantissa per memorizzare in modo completamente accurato anche l'ora UNIX attuale in secondi.

Perché memorizzi questi timestamp? Speri di farlo

  WHERE table.timestamp = 1357609984.100000

o query simili per cercare elementi particolari? Questo è irto di pericoli se usi numeri float o double in qualsiasi punto della tua catena di elaborazione (ovvero, anche se usi microtime(true) ancora una volta). Sono noti per non essere uguali anche quando pensavi che avrebbero dovuto. Invece devi usare qualcosa del genere. Il 0.001 è chiamato "epsilon" nel commercio di elaborazione numerica.

  WHERE table.timestamp BETWEEN 1357609984.100000 - 0.001
                            AND 1357609984.100000 + 0.001

o qualcosa di simile. Non avrai questo problema se memorizzi questi timestamp come decimali o in milionesimi di secondo in un bigint colonna.

IEEE in virgola mobile a 64 bit ha 53 bit di mantissa -- di precisione. L'attuale timestamp di UNIX Epoch (secondi dal 1 gennaio 1970 00:00Z) moltiplicato per un milione utilizza 51 bit. Quindi non c'è molta precisione in più nel DOUBLE se ci preoccupiamo del bit di basso ordine. D'altra parte, la precisione non si esaurirà per un paio di secoli.

Non sei affatto a corto di precisione con int64(BIGINT). Se stessi effettivamente memorizzando timestamp di microsecondi solo per ordinarli in MySQL, sceglierei DATETIME(6) perché otterrei un sacco di aritmetica della data gratuitamente. Se stessi facendo un'app in memoria ad alto volume, userei int64.