Ich habe eine Lösung, die Datenbanken und Tabellen durch Ausführen einiger Befehle konvertiert. Es wandelt auch alle Spalten des Typs varchar
, text
, tinytext
, mediumtext
, longtext
, char
. Sie sollten auch Ihre Datenbank sichern, falls etwas kaputt geht.
Kopieren Sie den folgenden Code in eine Datei mit dem Namen preAlterTables.sql:
use information_schema;
SELECT concat("ALTER DATABASE `",table_schema,"` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;") as _sql
FROM `TABLES` where table_schema like "yourDbName" group by table_schema;
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name,"` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") as _sql
FROM `TABLES` where table_schema like "yourDbName" group by table_schema, table_name;
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name, "` CHANGE `",column_name,"` `",column_name,"` ",data_type,"(",character_maximum_length,") CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",IF(is_nullable="YES"," NULL"," NOT NULL"),";") as _sql
FROM `COLUMNS` where table_schema like "yourDbName" and data_type in ('varchar','char');
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name, "` CHANGE `",column_name,"` `",column_name,"` ",data_type," CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",IF(is_nullable="YES"," NULL"," NOT NULL"),";") as _sql
FROM `COLUMNS` where table_schema like "yourDbName" and data_type in ('text','tinytext','mediumtext','longtext');
Ersetzen Sie alle Vorkommen von "yourDbName" durch die Datenbank, die Sie konvertieren möchten. Dann renne:
mysql -uroot < preAlterTables.sql | egrep '^ALTER' > alterTables.sql
Dadurch wird eine neue Datei alterTables.sql mit allen Abfragen generiert, die Sie zum Konvertieren der Datenbank benötigen. Führen Sie den folgenden Befehl aus, um die Konvertierung zu starten:
mysql -uroot < alterTables.sql
Sie können dies auch anpassen, um mehrere Datenbanken zu durchlaufen, indem Sie die Bedingung für table_schema ändern. Zum Beispiel table_schema like "wiki_%"
werden alle Datenbanken mit dem Namenspräfix konvertiert wiki_
. Um alle Datenbanken zu konvertieren, ersetzen Sie die Bedingung durch table_type!='SYSTEM VIEW'
.
Ein Problem, das auftreten könnte. Ich hatte einige varchar (255) Spalten in MySQL-Schlüsseln. Dies verursacht einen Fehler:
ERROR 1071 (42000) at line 2229: Specified key was too long; max key length is 767 bytes
In diesem Fall können Sie einfach die Spalte wie varchar (150) verkleinern und den Befehl erneut ausführen.
Bitte beachten Sie : Diese Antwort konvertiert die Datenbank in, utf8mb4_unicode_ci
anstatt utf8mb4_bin
, in der Frage gestellt. Aber Sie können dies einfach ersetzen.
mysql -uroot -pThatrootPassWord < alterTables.sql
. Und wie Sie bereits bemerkt haben, ist utf8mb4_bin unter anderem das, was nextcloud empfiehlt.Ich habe das folgende Shell-Skript verwendet. Es verwendet den Datenbanknamen als Parameter und konvertiert alle Tabellen in einen anderen Zeichensatz und eine andere Sortierung (angegeben durch einen anderen Parameter oder einen im Skript definierten Standardwert).
quelle
Ich würde ein Skript (in Perl oder was auch immer) schreiben, um information_schema (TABLES und COLUMNS) zu verwenden, um durch alle Tabellen zu gehen, und MODIFY COLUMN für jedes CHAR / VARCHAR / TEXT-Feld ausführen. Ich würde alle MODIFYs in einem einzigen ALTER für jede Tabelle sammeln; Dies wird effizienter sein.
Ich denke (bin mir aber nicht sicher), dass Raihans Vorschlag nur die Standardeinstellung für die Tabelle ändert .
quelle
Ist in diese Situation geraten; Hier ist der Ansatz, mit dem ich meine Datenbank konvertiert habe:
Zuerst müssen Sie bearbeiten
my.cnf
, um die Standarddatenbankverbindung (zwischen Anwendungen und MYSQL) utf8mb4_unicode_ci kompatibel zu machen. Ohne diese Zeichen wie Emojis und ähnliche, die von Ihren Apps gesendet werden, gelangen nicht in richtigen Bytes / Codierung in Ihre Tabellen (es sei denn, die DB CNN-Parameter Ihrer Anwendung geben eine utf8mb4-Verbindung an).Anweisungen hier gegeben .
Führen Sie die folgenden SQL-
ALTER TABLE
Anweisungen aus (SQL- Anweisungen müssen nicht vorbereitet werden, um einzelne Spalten zu ändern .)Bevor Sie den folgenden Code ausführen, ersetzen Sie "DbName" durch Ihren tatsächlichen DB-Namen.
Sammle und speichere die Ausgabe von oben genanntem SQL in einer Dot-SQL-Datei und führe sie aus.
Wenn Sie einen Fehler wie
#1071 - Specified key was too long; max key length is 1000 bytes.
zusammen mit dem problematischen Tabellennamen erhalten, bedeutet dies, dass der Indexschlüssel für eine Spalte dieser Tabelle (die in MB4-Zeichenfolge konvertiert werden sollte) sehr groß ist, daher sollte die Varchar-Spalte <= 250 sein Der Indexschlüssel ist maximal 1000 Byte groß. Überprüfen Sie die Spalten, für die Sie Indizes haben, und wenn eine von ihnen ein varchar> 250 (höchstwahrscheinlich 255) ist, dannSchritt 1: Überprüfen Sie die Daten in dieser Spalte, um sicherzustellen, dass die maximale Zeichenfolgengröße in dieser Spalte <= 250 ist.
Beispielabfrage:
Schritt 2: Wenn die maximale Länge der indizierten Spaltendaten <= 250 ist, ändern Sie die Spaltenlänge in 250. Wenn dies nicht möglich ist, entfernen Sie den Index für diese Spalte
Schritt 3: Führen Sie anschließend die Abfrage alter table für diese Tabelle erneut aus. Die Tabelle sollte nun erfolgreich in utf8mb4 konvertiert werden.
Prost!
quelle
Ich habe dieses Handbuch geschrieben: http://hanoian.com/content/index.php/24-automate-the-converting-a-mysql-database-character-set-to-utf8mb4
Bei meiner Arbeit habe ich gesehen, dass ALTER die Datenbank und die Tabellen nicht ausreichen. Ich musste in jede Tabelle gehen und auch jede der Spalten text / mediumtext / varchar ÄNDERN.
Zum Glück konnte ich ein Skript schreiben, um die Metadaten von MySQL-Datenbanken zu erkennen, sodass die Tabellen und Spalten durchlaufen und automatisch geändert werden konnten.
Langer Index für MySQL 5.6:
Sie müssen über die Berechtigung DBA / SUPER USER verfügen, um Folgendes zu tun: Festlegen der Datenbankparameter:
In den Antworten auf diese Frage finden Sie Anweisungen zum Festlegen dieser Parameter: https://stackoverflow.com/questions/35847015/mysql-change-innodb-large-prefix
Natürlich gibt es in meinem Artikel auch Anweisungen dazu.
Ab MySQL-Version 5.7 ist innodb_large_prefix standardmäßig aktiviert, und innodb_file_format ist ebenfalls standardmäßig Barracuda.
quelle
Für Leute, die dieses Problem haben könnten, ist die beste Lösung, zuerst die Spalten in einen binären Typ zu ändern, entsprechend dieser Tabelle:
Anschließend ändern Sie die Spalte wieder auf den vorherigen Typ und geben den gewünschten Zeichensatz ein.
Z.B.:
Ich habe es in mehreren lateinischen Tischen versucht und es hat alle diakritischen Punkte bewahrt.
Sie können diese Abfrage für alle Spalten extrahieren, die dies tun:
quelle
Ich habe ein Skript erstellt, das dies mehr oder weniger automatisch ausführt:
quelle