Bietet Rezepte, Lösungen und ausführliche Beispiele rund um gesundes SQL und zufriedene Datenbanken.
Durch die Globalisierung werden immer häufiger die Daten UTF-8 kodiert gespeichert. Das früher häufig verwendete Latin1 wird seltener. Das Problem ist nun der "mischmasch" von Zeichensätzen. Jeder kennt wahrscheinlich das T-Shirt mit dem "Schei? Encoding" Spruch. Ein Klassiker!
Um Probleme wie diese "Warning: #1366 Incorrect string value ..." zu vermeiden, hilft (hoffentlich) folgender Encoding-Check.
* MySQL 5.1.30
Schauen wir uns die Server-System-Variablen an. Achtung, die System-Variablen existieren als SESSION und GLOBAL Version. Beide müssen geprüft werden. Beginnen wir mit dem CHARSET:
mysql> show session variables like 'char%';+--------------------------+----------------------------------------------+| Variable_name | Value |+--------------------------+----------------------------------------------+| character_set_client | latin1 || character_set_connection | latin1 || character_set_database | latin1 || character_set_filesystem | binary || character_set_results | latin1 || character_set_server | latin1 || character_set_system | utf8 || character_sets_dir | G:\MySQL\MySql-Server-5.1.30\share\charsets\ |+--------------------------+----------------------------------------------+8 rows in set (0.01 sec)mysql> show global variables like 'char%';+--------------------------+----------------------------------------------+| Variable_name | Value |+--------------------------+----------------------------------------------+| character_set_client | latin1 || character_set_connection | latin1 || character_set_database | latin1 || character_set_filesystem | binary || character_set_results | latin1 || character_set_server | latin1 || character_set_system | utf8 || character_sets_dir | G:\MySQL\MySql-Server-5.1.30\share\charsets\ |+--------------------------+----------------------------------------------+8 rows in set (0.01 sec)Neben dem CHARSET gibt es auch noch die Sortierung (Collation).
mysql> show session variables like 'coll%';+----------------------+-------------------+| Variable_name | Value |+----------------------+-------------------+| collation_connection | latin1_swedish_ci || collation_database | latin1_swedish_ci || collation_server | latin1_swedish_ci |+----------------------+-------------------+3 rows in set (0.00 sec)mysql> show global variables like 'coll%';+----------------------+-------------------+| Variable_name | Value |+----------------------+-------------------+| collation_connection | latin1_swedish_ci || collation_database | latin1_swedish_ci || collation_server | latin1_swedish_ci |+----------------------+-------------------+3 rows in set (0.00 sec)Die MySQL Konfiguration haben wir nun geprüft. Aber neben der Server-Konfiguration können auch einzelne Tabellenspalten ein spezielles Character Set zugewiesen bekommen. Wie kann dies validiert werden?
Hinter dem INFORMATION_SCHEMA verstecken sich die Metadaten der MySQL-Datenbank. Hier sind die Tabellenstrukturen und vieles mehr hinterlegt. Das schönste dabei ist, das Information_schema basiert selbst auf Tabellen, die mit SQL abgefragt werden können.
/*** Welche CHARSET sind auf Spaltenebene definiert?*/SELECT character_set_name, COUNT(*) AS anzahlFROM information_schema.columnsWHERE character_set_name IS NOT NULLGROUP BY character_set_name;+--------------------+--------+| character_set_name | anzahl |+--------------------+--------+| latin1 | 720 || utf8 | 514 |+--------------------+--------+2 rows in set (3.83 sec)Also bei vielen Spalten ist explizit der Charset latin1 bzw. utf8 angegeben. In welchen Tabellen und Spalten ist nun latin1 definiert?
/*** Welcher Tabellenspalte ist explizit 'latin1' zugewiesen?*/SELECT table_catalog, table_schema, table_name, column_nameFROM information_schema.columnsWHERE character_set_name = 'latin1'ORDER BY table_catalog, table_schema, table_name, column_name;+---------------+--------------+------------------+-------------+| table_catalog | table_schema | table_name | column_name |+---------------+--------------+------------------+-------------+| NULL | lager | wx1 | comment || NULL | lager | wx1 | link || NULL | lager | wx1 | node |...720 rows in set (0.17 sec)In diesen Tabellen und Spalten hat sich somit noch ein "latin1" versteckt.
Ab MySQL Version 5 kann dies beispielweise so erfolgen.
mysql> ALTER TABLE wx1 CONVERT TO CHARACTER SET utf8;Detailierte Informationen (englisch) was beim Umstellen des Zeichensatzes zu beachten ist, gibt es hier: MySQL Performance Blog