Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Länge des MySQL-Varchar-Index

Sept. 2021 edit:Ich benutze MySQL 8.0 jetzt seit ein paar Jahren, also hier ein paar aktualisierte Informationen.

Das MySQL-Handbuch hat jetzt eine sehr informative Seite bezüglich Konvertierung zwischen utf8mb3 (aktuell auch bekannt als utf8 ) und utf8mb4 . utf8mb3 ist veraltet und wird entfernt letztlich; und wenn es entfernt wird, sein aktueller Alias, utf8 , bezieht sich auf utf8mb4 stattdessen.

Mit veraltetem utf8mb3 , können Sie bis zu 255 Zeichen in einem Index speichern, während Sie mit utf8mb4 , bis zu 191, wenn COMPACT verwendet wird oder REDUNDANT Zeilenformat.

Mit COMPRESSED oder DYNAMIC Zeilenformat können Indexschlüsselpräfixe bis zu 3072 Byte umfassen. Damit können Sie bis zu 1024 Zeichen für utf8mb3 indizieren , und 768 Zeichen für utf8mb4 .

Unten ist meine vorherige Antwort, die einen Teil der Logik hinter der Anzahl der Zeichen erklärt Sie können die Anzahl der Bytes indizieren .

Ich muss meine Antwort aufgrund meiner Recherche revidieren. Ursprünglich habe ich Folgendes gepostet (wobei ich mich selbst zitiere):

Ich glaube, die Antwort ist, dass Sie nicht wissen können, wie viele Zeichen im Index sein werden, weil Sie nicht wissen können, wie viele Bytes Ihre Zeichen haben werden (es sei denn, Sie tun etwas, um Multibyte-Zeichen auszuschließen).

Und ich bin mir nicht sicher, aber es könnte immer noch richtig sein, aber nicht ganz so, wie ich dachte.

Hier ist die richtige Antwort:

MySQL geht von 3 Bytes pro utf8-Zeichen aus. 255 Zeichen ist die maximale Indexgröße, die Sie pro Spalte angeben können, da 256 x 3 =768 die 767-Byte-Grenze überschreitet.

Wenn Sie keine Indexgröße angeben, wählt MySQL die maximale Größe (d. h. 255 pro Spalte). Eine UNIQUE-Einschränkung kann nicht auf eine utf8-Spalte angewendet werden, deren Länge größer als 255 ist, da ein eindeutiger Index den gesamten Zellenwert enthalten muss. Aber ein normaler Index kann verwendet werden - er indiziert nur die ersten 255 Zeichen (oder die ersten 767 Bytes?). Und da gibt es für mich noch ein Rätsel.

Das MySTERY:I kann sehen, warum MySQL aus Sicherheitsgründen 3 Bytes pro Zeichen annimmt, weil sonst die UNIQUE-Einschränkung gebrochen werden könnte. Aber die Dokumente scheinen darauf hinzudeuten, dass der Index tatsächlich in Bytes und nicht in Zeichen bemessen ist. Angenommen, Sie geben 255 ein char (765 Byte) Index auf einem varchar(256 ) Säule. Wenn die von Ihnen gespeicherten Zeichen alle ASCII-1-Byte-Zeichen sind, wie A-Z, a-z, 0-9, dann können Sie die gesamte Spalte in den 767-Byte-Index einfügen. Und es scheint, als würde das tatsächlich passieren.

Nachfolgend finden Sie weitere Informationen aus meiner ursprünglichen Antwort zu Zeichen, Bytes usw.

Laut Wikipedia , UTF-8-Zeichen kann 1, 2, 3 oder 4 Bytes lang sein. en/innodb-restrictions.html">diese MySQL-Dokumentation , beträgt die maximale Zeichengröße 3 Byte, sodass jeder Spaltenindexindex mit mehr als 255 Zeichen diese Byte-Grenze erreichen kann. Aber so wie ich es verstehe, vielleicht nicht. Wenn die meisten Ihrer Zeichen im ASCII-Bereich liegen, liegt Ihre durchschnittliche Zeichengröße näher bei 1 Byte. Wenn Ihre durchschnittliche Zeichengröße beispielsweise 1,3 Byte beträgt (meistens 1 Byte, aber eine beträchtliche Anzahl von 2-3 Byte-Zeichen), dann könnten Sie einen Index von 767/1,3

angeben

Wenn Sie also hauptsächlich 1-Byte-Zeichen speichern, wäre Ihr tatsächliches Zeichenlimit eher so:767 / 1,3 =590. Aber es stellt sich heraus, dass es nicht so funktioniert. 255 Zeichen ist das Limit.

Wie in dieser MySQL-Dokumentation erwähnt ,

Präfixgrenzen werden in Bytes gemessen, während die Präfixlänge in CREATE INDEX-Anweisungen als Anzahl von Zeichen für nichtbinäre Datentypen (CHAR, VARCHAR, TEXT) interpretiert wird. Berücksichtigen Sie dies, wenn Sie eine Präfixlänge für eine Spalte angeben, die einen Multibyte-Zeichensatz verwendet.

Es scheint, dass MySQL den Leuten rät, eine Berechnung / Schätzung durchzuführen, wie ich es gerade getan habe, um Ihre Schlüsselgröße für eine varchar-Spalte zu bestimmen. Aber eigentlich können Sie das nicht Geben Sie für UTF8-Spalten einen Index größer als 255 an.

Schließlich, wenn Sie noch einmal auf meinen zweiten Link verweisen, gibt es auch das:

Wenn die Konfigurationsoption innodb_large_prefix aktiviert ist, wird diese Längenbegrenzung für InnoDB-Tabellen, die die Zeilenformate DYNAMIC und COMPRESSED verwenden, auf 3072 Bytes erhöht.

Es scheint also, als könnten Sie mit ein wenig Anpassung viel größere Indizes erhalten, wenn Sie möchten. Stellen Sie einfach sicher, dass die Zeilenformate DYNAMISCH oder KOMPRIMIERT sind. Sie können in diesem Fall wahrscheinlich einen Index von 1023 oder 1024 Zeichen angeben.

Übrigens stellt sich heraus, dass Sie 4-Byte-Zeichen mit [dem utf8mb4-Zeichensatz][4] speichern können. Der utf8-Zeichensatz speichert anscheinend nur [„Plane 0“-Zeichen][5].

BEARBEITEN:

Ich habe gerade versucht, einen zusammengesetzten Index für eine varchar(511)-Spalte mit einer tinyint(1)-Spalte zu erstellen, und erhielt die Fehlermeldung, dass die maximale Indexgröße 767 Bytes betrug. Dies lässt mich glauben, dass MySQL davon ausgeht, dass utf8-Zeichensatzspalten 3 Bytes pro Zeichen (das Maximum) enthalten, und Ihnen erlaubt, maximal 255 Zeichen zu verwenden. Aber vielleicht geht das nur mit zusammengesetzten Indizes. Ich werde meine Antwort aktualisieren, wenn ich mehr herausfinde. Aber im Moment lasse ich das als Bearbeitung.