Mysql
 sql >> Baza danych >  >> RDS >> Mysql

DECIMAL długość dla mikroczasu (prawda)?

tl; dr. Użyj microtime(false) i przechowuj wyniki w bigint MySQL jako milionowe części sekundy. W przeciwnym razie musisz nauczyć się wszystkiego o arytmetyce zmiennoprzecinkowej, która jest wielką, grubą kulą włosową.

Funkcja mikroczasu PHP pobiera uniksowy znacznik czasu (obecnie około szesnastkowy 50eb7c00 lub dziesiętny 1.357.609.984) z jednego wywołania systemowego oraz czas w mikrosekundach z innego wywołania systemowego. Następnie przekształca je w ciąg znaków. Następnie, jeśli wywołasz to z (true), konwertuje tę liczbę na 64-bitową liczbę zmiennoprzecinkową IEEE 745, coś, co PHP nazywa float .

Na dzień dzisiejszy potrzebujesz dziesięciu cyfr dziesiętnych z lewej strony przecinka, aby zapisać całkowity znacznik czasu UNIX. Pozostanie to prawdą do około 2280 roku n.e., kiedy twoi potomkowie zaczną potrzebować jedenastu cyfr. Potrzebujesz sześciu cyfr z prawej strony miejsca dziesiętnego, aby zapisać mikrosekundy.

Nie uzyskasz całkowitej dokładności w mikrosekundach. Większość systemów utrzymuje zegar systemowy poniżej sekundy z rozdzielczością w zakresie 1-33 milisekund. To zależy od systemu.

MySQL w wersji 5.6.4 i nowszych pozwala na określenie DATETIME(6) kolumn, w których będą przechowywane daty i godziny z dokładnością do mikrosekund. Jeśli używasz takiej wersji MySQL, jest to absolutna droga.

Przed wersją 5.6.4 musisz użyć MySQL DOUBLE (IEEE 754 64-bitowa liczba zmiennoprzecinkowa) do przechowywania tych liczb. MySQL FLOAT (IEEE 754 32-bitowa liczba zmiennoprzecinkowa) nie ma wystarczającej liczby bitów w swojej mantysie, aby całkowicie dokładnie przechowywać nawet aktualny czas UNIX w sekundach.

Dlaczego przechowujesz te sygnatury czasowe? Czy masz nadzieję to zrobić

  WHERE table.timestamp = 1357609984.100000

lub podobne zapytania w celu wyszukania określonych pozycji? Jest to niebezpieczne, jeśli użyjesz liczb zmiennoprzecinkowych lub podwójnych w dowolnym miejscu łańcucha przetwarzania (to znaczy, nawet jeśli używasz microtime(true) nawet raz). Są znani z tego, że nie są równi, nawet jeśli myślałeś, że powinni. Zamiast tego musisz użyć czegoś takiego. 0.001 Nazywa się „epsilon” w branży przetwarzania numerycznego.

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

lub coś podobnego. Nie będziesz miał tego problemu, jeśli przechowujesz te znaczniki czasu jako ułamki dziesiętne lub w milionowych częściach sekundy w bigint kolumna.

64-bitowy zmiennoprzecinkowy IEEE ma 53 bity mantysy -- precyzji. Obecny znacznik czasu UNIX Epoch (sekundy od 1 stycznia 1970 r. 00:00Z) pomnożony przez milion wykorzystuje 51 bitów. Tak więc w DOUBLE nie ma zbyt wiele dodatkowej precyzji, jeśli zależy nam na bitach niskiego rzędu. Z drugiej strony precyzja nie wyczerpie się przez kilka stuleci.

Dzięki int64(BIGINT) nigdzie nie zabraknie Ci precyzji. Gdybym faktycznie przechowywał mikrosekundowe znaczniki czasu tylko w celu ich uporządkowania w MySQL, wybrałbym DATETIME(6) ponieważ dostałbym dużo arytmetyki dat za darmo. Gdybym robił aplikację o dużej objętości w pamięci, użyłbym int64.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Porządkowanie pozycji z pasującymi tagami według liczby pasujących tagów

  2. Od sygnatury czasowej w SQL, wybierając rekordy z dzisiaj, wczoraj, w tym tygodniu, w tym miesiącu i pomiędzy dwiema datami php mysql

  3. Jaki jest najlepszy sposób na migrację Django DB z SQLite do MySQL?

  4. jak wydrukować rekord z bazy danych, gdy użytkownik wybiera opcje z menu rozwijanego? program dynamiczny

  5. Schemat bazy danych Wufoo — jak byś go zaprojektował?