Mysql
 sql >> база данни >  >> RDS >> Mysql

DECIMAL дължина за микровреме (вярно)?

tl;dr. Използвайте microtime(false) и запазете резултатите в MySQL bigint като милионни секунди. В противен случай ще трябва да научите всичко за аритметиката с плаваща запетая, която е голяма дебела топка.

Функцията за микровреме на PHP грабва времевата марка на Unix (в момента около шестнадесетичен 50eb7c00 или десетичен 1,357,609,984) от едно системно повикване и микросекундното време от друго системно повикване. След това ги превръща в символен низ. След това, ако го извикате с (true), той преобразува това число в 64-битово число с плаваща запетая IEEE 745, нещо, което PHP нарича float .

Към днешна дата имате нужда от десет десетични цифри вляво от десетичната запетая, за да съхраните цяло число UNIX времеви печат. Това ще остане вярно до около 2280 г., когато вашите потомци ще започнат да се нуждаят от единадесет цифри. Ще ви трябват шест цифри вдясно от десетичната запетая, за да съхраните микросекундите.

Няма да получите пълна микросекундна точност. Повечето системи поддържат системния си часовник под секунда с разделителна способност от нещо в диапазона от 1-33 милисекунди. Зависи от системата.

MySQL версия 5.6.4 и по-нови ви позволяват да посочите DATETIME(6) колони, които ще съдържат дати и часове до микросекундна разделителна способност. Ако използвате такава версия на MySQL, това е абсолютно правилният начин.

Преди версия 5.6.4, трябва да използвате MySQL DOUBLE (IEEE 754 64-битова плаваща запетая), за да съхранявате тези числа. MySQL FLOAT (IEEE 754 32-битова плаваща запетая) няма достатъчно битове в своята мантиса, за да съхрани напълно точно дори сегашното UNIX време в секунди.

Защо съхранявате тези времеви марки? Надявате ли се да направите

  WHERE table.timestamp = 1357609984.100000

или подобни заявки за търсене на конкретни елементи? Това е изпълнено с опасност, ако използвате float или двойни числа навсякъде във вашата верига за обработка (тоест, дори ако използвате microtime(true) дори веднъж). Те са известни с това, че не са равни, дори когато си мислите, че трябва. Вместо това трябва да използвате нещо подобно. 0.001 се нарича "епсилон" в търговията с цифрова обработка.

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

или нещо подобно. Няма да имате този проблем, ако съхранявате тези времеви марки като десетични знаци или в милионни секунди в bigint колона.

IEEE 64-битовата плаваща запетая има 53 бита мантиса - с точност. Настоящата времева марка UNIX Epoch (секунди от 1 януари 1970 г. 00:00 Z) умножена по един милион използва 51 бита. Така че няма много допълнителна прецизност в DOUBLE, ако ни е грижа за бит от нисък ред. От друга страна, точността няма да изтече след няколко века.

Не сте близо до изчерпване на точността с int64(BIGINT). Ако всъщност съхранявах микросекундни времеви марки само за подреждането им в MySQL, щях да използвам DATETIME(6) защото щях да получа много аритметика за дати безплатно. Ако правех приложение с голям обем в паметта, бих използвал 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. Кога да използвате единични кавички, двойни кавички и обратни кавички в MySQL

  2. не може да се свърже с mysql docker от локално

  3. MySQL:изберете * от таблицата, където col IN (null, ) е възможно без ИЛИ

  4. Защо даденият синтаксис е валиден в mysql?

  5. SQLAlchemy:Как да изтрия с присъединяване