1. Problembeschreibung root@mysqldb 22:12: [xucl]> zeige Tabelle erstellen t1\G *************************** 1. Reihe *************************** Tabelle: t1 Tabelle erstellen: CREATE TABLE `t1` ( `id` varchar(255) STANDARD NULL ) ENGINE=InnoDB STANDARD-CHARSET=utf8 1 Zeile im Satz (0,00 Sek.) root@mysqldb 22:19: [xucl]> wähle * aus t1; +--------------------+ |Ich würde| +--------------------+ | 204027026112927605 | | 204027026112927603 | | 2040270261129276 | | 2040270261129275 | | 100 | | 101 | +--------------------+ 6 Zeilen im Satz (0,00 Sek.) Seltsames Phänomen: root@mysqldb 22:19: [xucl]> wähle * von t1, wobei id=204027026112927603; +--------------------+ |Ich würde| +--------------------+ | 204027026112927605 | | 204027026112927603 | +--------------------+ 2 Zeilen im Satz (0,00 Sek.) 640?wx_fmt=jpeg Was zur Hölle, ich habe 204027026112927603 überprüft, warum kam auch 204027026112927605 heraus? 2. Quellcode-Erklärung Die Aufrufstapelbeziehung ist wie folgt: JOIN::exec() ist der Ausführungseintrittspunkt und Arg_comparator::compare_real() ist eine Funktion zur Beurteilung gleicher Werte, die wie folgt definiert ist int Arg_comparator::compare_real() { /* Beheben Sie eine weitere Manifestation von Bug#2338. 'Volatile' weist an gcc zum Löschen von doppelten Werten aus 80-Bit-Intel-FPU-Registern vor Durchführen des Vergleichs. */ flüchtiger doppelter Wert1, Wert2; val1= (*a)->val_real(); wenn (!(*a)->null_wert) { val2 = (*b)->val_real(); wenn (!(*b)->null_wert) { wenn (null setzen) Besitzer->Nullwert = 0; wenn (Wert1 < Wert2) returniere -1; wenn (Wert1 == Wert2) gibt 0 zurück; Rückgabe 1; } } wenn (null setzen) Besitzer->Nullwert = 1; Rückgabe -1; } Die Vergleichsschritte sind in der folgenden Abbildung dargestellt. Die ID-Spalte der t1-Tabelle wird zeilenweise gelesen und in val1 eingefügt. Die Konstante 204027026112927603 existiert im Cache und ihr Typ ist doppelt (2,0402702611292762E+17). Daher gilt nach der Übergabe des Wertes an val2: val2=2,0402702611292762E+17. Beim Scannen bis zur ersten Zeile beträgt der in Doule umgewandelte Wert von 204027026112927605 2,0402702611292762e17. Die Gleichung wird erstellt, es wird festgestellt, dass es sich um eine qualifizierte Zeile handelt, und der Scan wird fortgesetzt. In ähnlicher Weise erfüllt auch 204027026112927603 die Bedingungen. Wie kann man feststellen, ob die Konvertierung von Zahlen vom Typ String in den Typ Double überläuft? Nach dem Test hier ist die Konvertierung in den Typ Double nicht mehr genau, wenn die Zahl 16 Ziffern überschreitet. Beispielsweise wird 20402702611292711 als 20402702611292712 ausgedrückt (wie in val1 in der Abbildung gezeigt). Die Definitionsfunktion zum Konvertieren von MySQL-Strings in Double lautet wie folgt: { Zeichenpuffer [DTOA_BUFF_SIZE]; doppelte Auflösung; DBUG_ASSERT(Ende != NULL && ((str != NULL && *Ende != NULL) || (str == NULL && *end == NULL)) && Fehler != NULL); res = my_strtod_int(str, Ende, Fehler, Puffer, Größe von(Puffer)); Rückgabe (*Fehler == 0)? res: (res < 0? -DBL_MAX: DBL_MAX); } Die eigentliche Konvertierungsfunktion my_strtod_int befindet sich in dtoa.c (zu kompliziert, einfach einen Kommentar posten) /* strtod für IEEE-Rechenmaschinen. Dieser Strtod gibt die nächste Maschinennummer zur eingegebenen Dezimalzahl zurück. string (oder setzt errno auf EOVERFLOW). Gleichstände werden durch die IEEE-Rundungsgleichung aufgelöst. Regel. Inspiriert von William D. Clingers Aufsatz „How to Read Floating Punktnummern genau angeben" [Proc. ACM SIGPLAN '90, Seiten 92-101]. Änderungen: 1. Wir benötigen nur IEEE (nicht IEEE Double-Extended). 2. Wir kommen mit Gleitkommaarithmetik aus, wenn Clinger verpasst -- wenn wir d * 10^n berechnen für eine kleine Ganzzahl d und die Ganzzahl n ist nicht zu viel größer als 22 (die maximale Ganzzahl k, für die wir können 10^k genau darstellen), können wir vielleicht Berechnen Sie (d*10^k) * 10^(ek) mit nur einer Rundung. 3. Anstatt einer schrittweisen Anpassung des Binärcodes Als Ergebnis verwenden wir im harten Fall Gleitkommazahlen Arithmetik zur Bestimmung der Anpassung innerhalb ein bisschen; nur in wirklich schwierigen Fällen müssen wir Berechnen Sie einen zweiten Rest. 4. Wegen 3. brauchen wir keine große Tabelle mit Zehnerpotenzen für zehn zu e (nur einige kleine Tabellen, z. B. von 10^k für 0 <= k <= 22). */ In diesem Fall testen wir den Fall, in dem es keinen Überlauf gibt root@mysqldb 23:30: [xucl]> wähle * von t1, wobei id=2040270261129276; +------------------+ |Ich würde| +------------------+ | 2040270261129276 | +------------------+ 1 Zeile im Satz (0,00 Sek.) root@mysqldb 23:30: [xucl]> wähle * von t1, wo id=101; +------+ |Ich würde| +------+ | 101 | +------+ 1 Zeile im Satz (0,00 Sek.) Das Ergebnis ist wie erwartet, und in diesem Fall sollte es korrekt so geschrieben werden: root@mysqldb 22:19: [xucl]> wähle * von t1, wobei id='204027026112927603'; +--------------------+ |Ich würde| +--------------------+ | 204027026112927603 | +--------------------+ 1 Zeile im Satz (0,01 Sek.) Abschluss Vermeiden Sie implizite Typkonvertierungen. Implizite Konvertierungen umfassen hauptsächlich inkonsistente Feldtypen, mehrere Typen im In-Parameter, inkonsistente Zeichensatztypen oder Korrekturleseregeln usw. Implizite Typkonvertierungen können dazu führen, dass Indizes nicht verwendet werden können, die Abfrageergebnisse ungenau sind usw. Sie müssen sie daher bei der Verwendung sorgfältig identifizieren. Es wird empfohlen, den numerischen Typ beim Definieren des Felds als int oder bigint zu definieren. Wenn die Tabelle verknüpft ist, müssen die zugehörigen Felder denselben Typ, Zeichensatz und dieselben Sortierregeln aufweisen. Abschließend möchte ich die Beschreibung der impliziten Typkonvertierung auf der offiziellen Website veröffentlichen.
Zusammenfassen Das Obige ist die vom Editor eingeführte implizite MySQL-Konvertierung. Ich hoffe, es wird allen helfen. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird Ihnen rechtzeitig antworten. Ich möchte auch allen für ihre Unterstützung der Website 123WORDPRESS.COM danken! Das könnte Sie auch interessieren:
|
<<: So ändern Sie die Systemsprache von CentOS7 in vereinfachtes Chinesisch
>>: jQuery benutzerdefinierter Lupeneffekt
Wenn der img src-Wert leer ist, werden zwei Anfrag...
Vorwort Es gibt viele Möglichkeiten, in CSS horiz...
1. Das Tabellen-Tag ist Tabelle, tr ist Zeile, td ...
Join-Abfrage Eine Join-Abfrage bezieht sich auf e...
Vorwort Bisher waren statische IPs, die über Pipe...
Vorwort add_header ist eine Direktive, die im Hea...
Lassen Sie uns zunächst verstehen, was Docker ist...
Dieser Artikel zeichnet das Installationstutorial...
In diesem Artikel finden Sie das Installations-Tu...
Sicht: Wenn eine temporäre Tabelle wiederholt ver...
Inhaltsverzeichnis Nginx-Lastausgleichskonfigurat...
Heute Wählen Sie * aus Tabellenname, wobei to_day...
In diesem Artikel wird der spezifische Code von j...
1. Laden Sie die virtuelle Maschine Version 15.5....
Vorwort: Ich habe neulich einen Alibaba-Cloud-Hos...