Die TIME
Werte wurden in MySQL immer auf 3 Bytes gespeichert. Aber das Format hat sich in Version 5.6 geändert .4
. Ich vermute, dass dies nicht das erste Mal war, dass es sich geändert hat. Aber die andere Veränderung, falls es eine gab, ist vor langer Zeit passiert und es gibt keinen öffentlichen Beweis dafür. Der Verlauf des MySQL-Quellcodes auf GitHub beginnt mit Version 5.5 (der älteste Commit stammt vom Mai 2008), aber die Änderung, nach der ich suche, geschah irgendwo zwischen 2001 und 2002 (MySQL 4 wurde 2003 eingeführt)
Das aktuelle Format, wie in der Dokumentation beschrieben, verwendet 6 Bits für Sekunden (mögliche Werte:0
bis 63
), 6 Bit für Minuten, 10 Bit für Stunden (mögliche Werte:0
bis 1023
), 1 Bit für Vorzeichen (addieren Sie die negativen Werte der bereits erwähnten Intervalle) und 1 Bit ist unbenutzt und mit "reserviert für zukünftige Erweiterungen" gekennzeichnet.
Es ist für die Arbeit mit Zeitkomponenten (Stunden, Minuten, Sekunden) optimiert und verschwendet nicht viel Platz. Mit diesem Format ist es möglich, Werte zwischen -1023:59:59
zu speichern und +1023:59:59
. Allerdings begrenzt MySQL die Anzahl der Stunden auf 838
, wahrscheinlich aus Gründen der Abwärtskompatibilität mit Anwendungen, die vor einiger Zeit geschrieben wurden, als ich denke, dass dies die Grenze war.
Bis Version 5.6.4 ist die TIME
Werte wurden auch auf 3 Bytes gespeichert und die Komponenten wurden als days * 24 * 3600 + hours * 3600 + minutes * 60 + seconds
gepackt . Dieses Format wurde für die Arbeit mit Zeitstempeln optimiert (weil es tatsächlich ein Zeitstempel war). Mit diesem Format wäre es möglich, Werte im Bereich von etwa -2330
zu speichern an +2330
Std. Obwohl dieser große Wertebereich verfügbar war, beschränkte MySQL die Werte immer noch auf -838
an +838
Std.
Es gab Bug #11655
auf MySQL 4. Es war möglich, TIME
zurückzugeben Werte außerhalb von -838..+838
Bereich mit verschachteltem SELECT
Aussagen. Es war kein Feature, sondern ein Fehler, der behoben wurde.
Der einzige Grund, die Werte auf diesen Bereich zu beschränken und aktiv jeden Code zu ändern, der TIME
erzeugt Werte außerhalb davon war Abwärtskompatibilität.
Ich vermute, dass MySQL 3 ein anderes Format verwendet hat, das aufgrund der Art und Weise, wie die Daten gepackt wurden, die gültigen Werte auf den Bereich -838..+838
beschränkte Stunden.
Durch einen Blick in den aktuellen Quellcode von MySQL Ich habe diese interessante Formel gefunden:
#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + TIME_MAX_SECOND)
Lassen Sie uns für den Moment das MAX
ignorieren Teil der oben verwendeten Namen und erinnern wir uns nur an diese TIME_MAX_MINUTE
und TIME_MAX_SECOND
sind Zahlen zwischen 00
und 59
. Die Formel verkettet einfach die Stunden, Minuten und Sekunden in einer einzigen Ganzzahl. Zum Beispiel der Wert 170:29:45
wird zu 1702945
.
Diese Formel wirft folgende Frage auf:Da die TIME
Werte werden auf 3 Bytes mit Vorzeichen gespeichert, was ist der maximale positive Wert, der auf diese Weise dargestellt werden kann?
Der gesuchte Wert ist 0x7FFFFF
das ist in Dezimalschreibweise 8388607
. Da die letzten vier Ziffern (8607
) sollte als Minuten gelesen werden (86
) und Sekunden (07
) und ihr maximal gültiger Wert ist 59
, ist der größte Wert, der auf 3 Bytes mit Vorzeichen unter Verwendung der obigen Formel gespeichert werden kann, 8385959
. Welche, als TIME
ist +838:59:59
. Ta-da!
Erraten Sie, was? Das Fragment von C
Der oben aufgeführte Code wurde daraus extrahiert:
/* 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)
Ich bin mir sicher, dass MySQL 3 auf diese Weise die TIME
beibehalten hat Werte intern. Dieses Format führte zu einer Beschränkung des Bereichs, und die Abwärtskompatibilitätsanforderung für die nachfolgenden Versionen propagierte die Beschränkung bis in unsere Tage.