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

Mengapa batas waktu maksimum MySQL 838:59:59?

TIME nilai selalu disimpan pada 3 byte di MySQL. Tapi formatnya berubah pada versi 5.6 .4 . Saya menduga ini bukan pertama kalinya ketika itu berubah. Tetapi perubahan lain, jika ada, terjadi sejak lama dan tidak ada bukti publik tentangnya. Riwayat kode sumber MySQL di GitHub dimulai dengan versi 5.5 (komit tertua adalah dari Mei 2008) tetapi perubahan yang saya cari terjadi di suatu tempat sekitar tahun 2001-2002 (MySQL 4 diluncurkan pada tahun 2003)

Format saat ini, seperti yang dijelaskan dalam dokumentasi, menggunakan 6 bit untuk detik (nilai yang mungkin:0 ke 63 ), 6 bit untuk menit, 10 bit untuk jam (nilai yang mungkin:0 ke 1023 ), 1 bit untuk tanda (tambahkan nilai negatif dari interval yang telah disebutkan) dan 1 bit tidak digunakan dan diberi label "dicadangkan untuk ekstensi mendatang".

Ini dioptimalkan untuk bekerja dengan komponen waktu (jam, menit, detik) dan tidak membuang banyak ruang. Dengan menggunakan format ini dimungkinkan untuk menyimpan nilai antara -1023:59:59 dan +1023:59:59 . Namun MySQL membatasi jumlah jam menjadi 838 , mungkin untuk kompatibilitas mundur dengan aplikasi yang ditulis beberapa waktu lalu, ketika saya pikir ini adalah batasnya.

Sampai versi 5.6.4, TIME nilai juga disimpan dalam 3 byte dan komponen dikemas sebagai days * 24 * 3600 + hours * 3600 + minutes * 60 + seconds . Format ini dioptimalkan untuk bekerja dengan stempel waktu (karena, pada kenyataannya, adalah stempel waktu). Dengan menggunakan format ini, dimungkinkan untuk menyimpan nilai dalam kisaran sekitar -2330 ke +2330 jam. Meskipun memiliki rentang nilai yang besar ini, MySQL masih membatasi nilainya menjadi -838 ke +838 jam.

Ada bug #11655 di MySQL 4. Dimungkinkan untuk mengembalikan TIME nilai di luar -838..+838 rentang menggunakan SELECT . bersarang pernyataan. Itu bukan fitur tetapi bug dan telah diperbaiki.

Satu-satunya alasan untuk membatasi nilai pada rentang ini dan untuk secara aktif mengubah setiap bagian kode yang menghasilkan TIME nilai di luarnya adalah kompatibilitas ke belakang.

Saya menduga MySQL 3 menggunakan format berbeda yang, karena cara data dikemas, membatasi nilai valid ke kisaran -838..+838 jam.

Dengan melihat kode sumber MySQL Saya menemukan rumus yang menarik ini:

#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + TIME_MAX_SECOND)

Mari kita abaikan sejenak MAX bagian dari nama yang digunakan di atas dan mari kita ingat hanya TIME_MAX_MINUTE dan TIME_MAX_SECOND adalah angka di antara 00 dan 59 . Rumus hanya menggabungkan jam, menit dan detik dalam satu bilangan bulat. Misalnya, nilai 170:29:45 menjadi 1702945 .

Rumus ini menimbulkan pertanyaan berikut:mengingat bahwa TIME nilai disimpan dalam 3 byte dengan tanda, berapa nilai positif maksimum yang dapat direpresentasikan dengan cara ini?

Nilai yang kita cari adalah 0x7FFFFF bahwa dalam notasi desimal adalah 8388607 . Sejak empat digit terakhir (8607 ) harus dibaca sebagai menit (86 ) dan detik (07 ) dan nilai valid maksimumnya adalah 59 , nilai terbesar yang dapat disimpan pada 3 byte dengan tanda menggunakan rumus di atas adalah 8385959 . Yang mana, sebagai TIME adalah +838:59:59 . Ta-da!

Tebak apa? Fragmen C kode yang tercantum di atas diambil dari ini:

/* Limits for the TIME data type */
#define TIME_MAX_HOUR 838
#define TIME_MAX_MINUTE 59
#define TIME_MAX_SECOND 59
#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + TIME_MAX_SECOND)

Saya yakin ini adalah bagaimana MySQL 3 digunakan untuk menjaga TIME nilai secara internal. Format ini memberlakukan batasan jangkauan, dan persyaratan kompatibilitas mundur pada versi berikutnya menyebarkan batasan tersebut hingga saat ini.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mengonversi tabel MySQL dengan data yang dikodekan secara salah ke UTF-8

  2. Cara Menghapus MySQL Dari Ubuntu Sepenuhnya

  3. MySQL COUNT dengan LIMIT

  4. Obrolan langsung dengan PHP dan jQuery. Di mana menyimpan informasi? Mysql atau file?

  5. Hibernate, JDBC dan kinerja Java pada set hasil menengah dan besar