Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Panjang DECIMAL untuk waktu mikro (benar)?

tl; dr. Gunakan microtime(false) dan simpan hasilnya di MySQL bigint sebagai sepersejuta detik. Jika tidak, Anda harus mempelajari semua tentang aritmatika floating point, yang merupakan bola rambut besar yang gemuk.

Fungsi waktu mikro PHP mengambil stempel waktu Unix (saat ini sekitar hex 50eb7c00 atau desimal 1.357.609.984) dari satu panggilan sistem, dan waktu mikrodetik dari panggilan sistem lain. Itu kemudian membuat mereka menjadi string karakter. Kemudian, jika Anda memanggilnya dengan (benar) itu mengubah nomor itu menjadi nomor floating point IEEE 745 64-bit, sesuatu yang PHP sebut sebagai float .

Mulai hari ini Anda memerlukan sepuluh digit desimal di sebelah kiri titik desimal untuk menyimpan stempel waktu UNIX bilangan bulat. Itu akan tetap benar sampai sekitar 2280 CE ketika keturunan Anda akan mulai membutuhkan sebelas digit. Anda memerlukan enam digit di sebelah kanan tempat desimal untuk menyimpan mikrodetik.

Anda tidak akan mendapatkan akurasi mikrodetik total. Sebagian besar sistem mempertahankan jam sistem sub-detik mereka dengan resolusi sekitar 1-33 milidetik. Ini bergantung pada sistem.

MySQL versi 5.6.4 dan yang lebih baru memungkinkan Anda untuk menentukan DATETIME(6) kolom, yang akan menyimpan tanggal dan waktu ke resolusi mikrodetik. Jika Anda menggunakan versi MySQL seperti itu, itulah cara yang tepat.

Sebelum versi 5.6.4, Anda harus menggunakan DOUBLE MySQL (IEEE 754 64-bit floating point) untuk menyimpan angka-angka ini. MySQL FLOAT (IEEE 754 32-bit floating point) tidak memiliki cukup bit dalam mantissanya untuk menyimpan bahkan waktu UNIX saat ini dalam hitungan detik secara akurat.

Mengapa Anda menyimpan stempel waktu ini? Apakah Anda berharap untuk melakukan

  WHERE table.timestamp = 1357609984.100000

atau pertanyaan serupa untuk mencari item tertentu? Itu penuh dengan bahaya jika Anda menggunakan angka float atau double di mana saja dalam rantai pemrosesan Anda (yaitu, bahkan jika Anda menggunakan microtime(true) bahkan sekali). Mereka terkenal karena tidak tampil setara bahkan ketika Anda pikir mereka harus melakukannya. Sebaliknya Anda perlu menggunakan sesuatu seperti ini. 0.001 Ini disebut "epsilon" dalam perdagangan pemrosesan numerik.

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

atau sesuatu yang serupa. Anda tidak akan mengalami masalah ini jika menyimpan stempel waktu ini sebagai desimal atau dalam sepersejuta detik dalam bigint kolom.

IEEE 64-bit floating point memiliki 53 bit mantissa -- presisi. Stempel waktu UNIX Epoch saat ini (detik sejak 1-Jan-1970 00:00Z) kali satu juta menggunakan 51 bit. Jadi tidak banyak presisi ekstra dalam DOUBLE jika kita peduli dengan bit orde rendah. Di sisi lain, presisi tidak akan habis selama beberapa abad.

Anda hampir kehabisan presisi dengan int64(BIGINT). Jika saya benar-benar menyimpan stempel waktu mikrodetik hanya untuk memesannya di MySQL, saya akan menggunakan DATETIME(6) karena saya akan mendapatkan banyak aritmatika tanggal secara gratis. Jika saya melakukan aplikasi volume tinggi dalam memori, saya akan menggunakan 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. Peringatan:mysqli_num_rows() mengharapkan tepat 1 parameter, 2 diberikan | mysql |mysqli

  2. Mengurutkan subpohon dalam struktur data hierarki tabel penutupan

  3. Masukkan data ke dalam tabel menggunakan php

  4. Bagaimana cara menautkan C++ MySQL Connector Library ke Cmake?

  5. Melewati FieldName sebagai Parameter dalam Prosedur Tersimpan MySQL