656 Stimmen

MySQL-Fehler #1071 - Der angegebene Schlüssel war zu lang; die maximale Schlüssellänge beträgt 767 Bytes

Wenn ich den folgenden Befehl ausführe:

ALTER TABLE `mytable` ADD UNIQUE (
`column1` ,
`column2`
);

Ich habe diese Fehlermeldung erhalten:

#1071 - Specified key was too long; max key length is 767 bytes

Informationen über Spalte1 und Spalte2:

column1 varchar(20) utf8_general_ci
column2  varchar(500) utf8_general_ci

でしょう varchar(20) benötigt nur 21 Bytes, während varchar(500) benötigt nur 501 Bytes. Die Gesamtzahl der Bytes beträgt also 522, also weniger als 767. Warum habe ich dann die Fehlermeldung erhalten?

#1071 - Specified key was too long; max key length is 767 bytes

5 Stimmen

Da es sich nicht um 520 Bytes, sondern um 2080 Bytes handelt, die weit über 767 Bytes hinausgehen, könnten Sie Spalte1 varchar(20) und Spalte2 varchar(170) verwenden. Wenn Sie eine Zeichen/Byte-Entsprechung wünschen, verwenden Sie latin1

3 Stimmen

Ich denke, Ihre Berechnung ist ein bisschen falsch hier. mysql verwendet 1 oder 2 zusätzliche Bytes, um die Werte Länge aufzeichnen: 1 Byte, wenn die maximale Länge der Spalte 255 Bytes oder weniger ist, 2, wenn es länger als 255 Bytes ist. die utf8_general_ci Codierung benötigt 3 Bytes pro Zeichen so varchar (20) verwendet 61 Bytes, varchar (500) verwendet 1502 Bytes insgesamt 1563 Bytes

3 Stimmen

Mysql> select maxlen, character_set_name from information_schema.character_sets where character_set_name in('latin1', 'utf8', 'utf8mb4'); maxlen | character_set_name ------ | ------------------- 1 | latin1 ------ | ------------------- 3 | utf8 ------ | ------------------- 4 | utf8mb4

58voto

Raza Ahmed Punkte 2561

Führen Sie diese Abfrage vor Ihrer Abfrage aus:

SET @@global.innodb_large_prefix = 1;

wird die Grenze auf 3072 bytes .

4 Stimmen

Gibt es einen Nachteil, wenn man global zu innodb_large_prefix wechselt? Und ist diese DB "global" oder sind alle DBs VOLLSTÄNDIG GLOBAL?

5 Stimmen

Gilt nur bei Verwendung von Nicht-Standard-Zeilenformaten. Siehe dev.mysql.com/doc/refman/5.5/de/ . Aktivieren Sie diese Option, um Indexschlüssel-Präfixe zuzulassen, die länger als 767 Byte (bis zu 3072 Byte) sind, für InnoDB-Tabellen, die die Zeilenformate DYNAMIC und COMPRESSED verwenden. Das Standard-Zeilenformat ist davon nicht betroffen.

5 Stimmen

Das hat bei mir gut funktioniert - weitere Einzelheiten und einen Leitfaden finden Sie hier: mechanics.flite.com/blog/2014/07/29/

40voto

Amber Punkte 473552

Welche Zeichenkodierung verwenden Sie? Einige Zeichensätze (wie UTF-16 usw.) verwenden mehr als ein Byte pro Zeichen.

9 Stimmen

Wenn es sich um UTF8 handelt, kann ein Zeichen bis zu 4 Bytes verwenden, so dass die Spalte mit 20 Zeichen 20 * 4 + 1 Bytes, und die 500-Zeichen-Spalte ist 500 * 4 + 2 Bytes

5 Stimmen

Für was es wert ist, ich hatte gerade das gleiche Problem und Umschalten von utf8_general_ci zu utf8_unicode_ci löste das Problem für mich. Ich weiß allerdings nicht, warum :(

11 Stimmen

Für eine VARCHAR(256) Spalte mit einer UNIQUE index, die Änderung der Sortierung hatte bei mir keine Auswirkung, wie bei @Andresch. Die Verringerung der Länge von 256 auf 255 hat das Problem jedoch gelöst. Ich verstehe nicht, warum, da 767 / max. 4 Bytes pro Zeichen ein Maximum von 191 ergeben würde?

34voto

Bryan Punkte 16215

Ersetzen Sie utf8mb4 con utf8 in Ihrer Importdatei.

enter image description here

3 Stimmen

Warum genau sollte man das tun? Wenn dies irgendwelche Nachteile hat (wovon ich ausgehe), sollten Sie außerdem Folgendes erwähnen

0 Stimmen

Dies bedeutet, dass Ihre Spalte einige Unicode-Zeichen nicht speichern kann, vor allem Emojis.

1 Stimmen

Wenn Sie laravel verwenden ... diese Lösung wird Ihnen Stunden sparen !!!

31voto

Buksy Punkte 10646

Ich glaube, varchar(20) benötigt nur 21 Bytes, während varchar(500) nur 501 Bytes benötigt. Die Gesamtzahl der Bytes beträgt also 522, weniger als 767. Warum also habe ich die Fehlermeldung erhalten?

UTF8 benötigt 3 Bytes pro Zeichen um die Zeichenfolge zu speichern, in Ihrem Fall also 20 + 500 Zeichen = 20*3+500*3 = 1560 Bytes, das ist mehr als erlaubt 767 Bytes.

Die Grenze für UTF8 ist 767/3 = 255 Zeichen für UTF8mb4, das 4 Bytes pro Zeichen verwendet, sind es 767/4 = 191 Zeichen.


Es gibt zwei Lösungen für dieses Problem, wenn Sie eine längere Spalte als den Grenzwert verwenden müssen:

  1. Verwenden Sie die "billigere" Kodierung (diejenige, die weniger Bytes pro Zeichen benötigt)
    In meinem Fall musste ich einen Unique-Index für die Spalte hinzufügen, die den SEO-String des Artikels enthält, da ich nur [A-z0-9\-] Zeichen für SEO, ich habe latin1_general_ci die nur ein Byte pro Zeichen verwendet, so dass die Spalte 767 Bytes lang sein kann.
  2. Erstellen Sie einen Hash aus Ihrer Spalte und verwenden Sie einen eindeutigen Index nur für diese Spalte
    Die andere Option für mich war es, eine weitere Spalte zu erstellen, die Hash von SEO speichern würde, diese Spalte würde haben UNIQUE Schlüssel, um sicherzustellen, dass die SEO-Werte eindeutig sind. Ich würde auch hinzufügen KEY Index zur ursprünglichen SEO-Spalte, um die Suche zu beschleunigen.

0 Stimmen

Das war der Trick. Ich hatte varchar(256) und musste es in varchar(250) ändern.

28voto

vee Punkte 3934

Die Antwort auf die Frage, warum Sie eine Fehlermeldung erhalten, wurde bereits von vielen Benutzern hier beantwortet. In meiner Antwort geht es darum, wie man die Fehlermeldung behebt und wie sie verwendet werden kann.

Siehe von dieser Link .

  1. Öffnen Sie den MySQL-Client (oder MariaDB-Client). Es handelt sich um ein Kommandozeilenwerkzeug.
  2. Es wird nach Ihrem Passwort gefragt, geben Sie Ihr richtiges Passwort ein.
  3. Wählen Sie Ihre Datenbank mit dem folgenden Befehl aus use my_database_name;

Datenbank geändert

  1. set global innodb_large_prefix=on;

Abfrage OK, 0 Zeilen betroffen (0.00 sec)

  1. set global innodb_file_format=Barracuda;

Abfrage OK, 0 Zeilen betroffen (0.02 sec)

  1. Rufen Sie Ihre Datenbank über phpMyAdmin oder ein ähnliches Programm auf, um die Verwaltung zu erleichtern. > Datenbank auswählen > Tabelle anzeigen Struktur > Weiter zu Betrieb Registerkarte. > Ändern REIHE_FORMAT à DYNAMISCH und speichern Sie die Änderungen.
  2. Zu den Tabellen Struktur Registerkarte > Klicken Sie auf Einzigartig Taste.
  3. Erledigt. Jetzt sollte es keine Fehler mehr geben.

Das Problem bei dieser Lösung ist, dass Sie die Datenbank auf einen anderen Server exportieren (z.B. von localhost auf realhost) und Sie die MySQL-Befehlszeile auf diesem Server nicht verwenden können. Sie können es dort nicht zum Laufen bringen.

0 Stimmen

Wenn Sie nach der Eingabe der obigen Abfrage immer noch einen Fehler erhalten, versuchen Sie, zu "phpmyadmin" zu gehen > stellen Sie die "Kollation" auf Ihre Präferenz ein (für mich verwende ich "utf8_general_ci") > klicken Sie auf "Anwenden" (auch wenn es bereits utf8 ist)

0 Stimmen

Ich benutze kein Tool, das mit Ihren Anweisungen funktioniert, aber ich stimme trotzdem dafür, dass ich versuche, Menschen zu helfen mit tatsächliche Festsetzung das Problem. Es gibt endlose Erklärungen über die Ursachen des Problems, aber bemerkenswert wenig darüber, wie man es tatsächlich lösen kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X