Bitte erläutern Sie, wie Wordpress mit dem MySQL-Zeichensatz und der Sortierung auf niedriger Ebene funktioniert

10

Wie aus dem Fragentitel hervorgeht, möchte ich verstehen, wie Wordpress mit MySQL-Zeichensätzen und Sortieroptionen funktioniert. Wie ich weiter unten zeigen werde, machen die Dinge für mich nicht viel Sinn ...

Ich habe Wordpress installiert, indem ich den Anweisungen auf der Installationsseite gefolgt bin:

https://codex.wordpress.org/Installing_WordPress

Als Teil der Anweisungen befolgte ich ihre Ratschläge zur manuellen Erstellung der MySQL-Datenbank in der Befehlszeile, nämlich die Befehle:

mysql> CREATE DATABASE databasename;
Query OK, 1 row affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON databasename.* TO "wordpressusername"@"hostname"
-> IDENTIFIED BY "password";
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql> EXIT

Außerdem habe ich, wie angewiesen, die Datei "wp-config.php" so bearbeitet, dass der UTF-8-Zeichensatz verwendet wird:

define( 'DB_CHARSET', 'utf8' );

... und ließ die Sortiereinstellung leer:

define( 'DB_COLLATE', '' );

Hier beginnt der Spaß ...

  1. Wenn ich ein Zeichen, das nicht Teil von MySQL UTF-8 ist, aber Teil von UTF-8 MB4 ist, wie z. B. 𝌆, in einen Beitrag eingebe, wird es auf der gerenderten Seite korrekt angezeigt. Ich hätte erwartet, dass dies nicht passiert, da ich den Zeichensatz nicht auf UTF-8 MB4 gesetzt habe, sondern auf den eingeschränkteren UTF-8 (wie von MySQL definiert, natürlich nicht so allgemein verstanden).

  2. Wenn ich das Problem in MySQL über die Befehlszeile untersuche, wird es seltsamer. Wenn ich renne show variables like 'char%';, bekomme ich folgende Antwort:

    +--------------------------+----------------------------+
    | Variable_name            | Value                      |
    +--------------------------+----------------------------+
    | character_set_client     | utf8                       |
    | character_set_connection | utf8                       |
    | character_set_database   | latin1                     |
    | character_set_filesystem | binary                     |
    | character_set_results    | utf8                       |
    | character_set_server     | latin1                     |
    | character_set_system     | utf8                       |
    | character_sets_dir       | /usr/share/mysql/charsets/ |
    +--------------------------+----------------------------+

Ich hätte erwartet, dass der Datenbankzeichensatz UTF-8 und nicht latin1 ist.

  1. Wenn ich den Befehl ausführe show variables like 'collation%';, lautet die Ausgabe:

    +----------------------+-------------------+
    | Variable_name        | Value             |
    +----------------------+-------------------+
    | collation_connection | utf8_general_ci   |
    | collation_database   | latin1_swedish_ci |
    | collation_server     | latin1_swedish_ci |
    +----------------------+-------------------+

Das ist aus offensichtlichen Gründen noch seltsamer (hätte die Standardkollatierung latin1_swedish_ci in einer UTF-8-Datenbank nicht erwartet).

  1. Wenn ich schließlich laufe show full columns from mywpdatabase.wp_posts;, zeigen die Ausgabezeilen, in denen der Wert nicht NULL ist, die folgende Kollatierung:

| post_content_filtered | longtext | utf8mb4_unicode_ci |

Meine Frage dann - wie kann das erklärt werden? Warum rendert meine Wordpress-Installation UTF-8 MB4-Zeichen korrekt, wenn die Datenbank in der Konfiguration als UTF-8 definiert ist? Und warum wird die Datenbank in MySQL als lateinische, schwedische Kollatierung anstelle von UTF-8 angezeigt? Und wie kommt es, dass die einzelnen Felder in der Tabelle trotz alledem utf8mb4_unicode_ci sind? Eine einfache Erklärung der Funktionsweise von Wordpress mit MySQL wäre sehr hilfreich. Vielen Dank!

X-Mann
quelle

Antworten:

11

In wp-config.php der WordPress-Website gibt es zwei Definitionen:

define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');

Es gibt mehrere Dinge, die am häufigsten missverstanden werden. Namen von Konstanten in diesen Definitionen deuten möglicherweise darauf hin, dass sie mit der Datenbank selbst zusammenhängen. Sie sind nicht. Sie beziehen sich auf Tabellen in der Datenbank.

Die Datenbankerstellung ist völlig unabhängig von der Tabellenerstellung. WordPress erstellt keine Datenbank und kümmert sich nicht um den Standardzeichensatz und die Sortierung der Datenbank, solange eine Verbindung zur Datenbank hergestellt werden kann.

Der Wert 'utf8' in der ersten Definition bedeutet, der am wenigsten eingeschränkte Zeichensatz aus der 'utf8'-Familie, der entweder' utf8 'oder' utf8mb4 'ist.

Wenn Sie die obigen Definitionen unverändert lassen, bevor Sie versuchen, Ihre Website zu installieren, müssen Sie WordPress anweisen, seine eigenen Entscheidungen hinsichtlich des Zeichensatzes und der Sortierung der Datenbanktabellen zu treffen, die von MySQL (abhängig von der MySQL-Version) unterstützt werden und am wenigsten einschränken.

Folgendes analysiert WordPress während der Installation, um seine Auswahl zu bestimmen:

  • MySQL-Version
  • Datenbankkollation (in wp-config.php)

Basierend auf der MySQL-Version entscheidet WordPress, welche Gruppe von utf8- Familien verwendet werden soll. Es gibt zwei, die sich durch ihre Namen unterscheiden: utf8 und utf8mb4 . Zeichensätze aus der Gruppe utf8 ermöglichen das Speichern von maximal 3 Byte langen Zeichen. Zeichensätze aus der Gruppe utf8mb4 ermöglichen das Speichern von maximal 4 Byte langen Zeichen.

Jetzt überprüft WordPress den Wert von DB_COLLATE define. Wenn leer, wird die am wenigsten einschränkende Sortierung aus der ausgewählten utf8- Familie verwendet, andernfalls wird der angegebene Wert verwendet.

Beispiele

define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');

Wenn MySQL utf8mb4 (ältere Versionen) nicht unterstützt, lautet der Tabellenzeichensatz utf8 und die Sortierung utf8_general_ci . Andernfalls können wir utf8mb4 und utf8mb4_unicode_520_ci bzw. utf8mb4_unicode_ci (MySQL-Version abhängig) erwarten .

define('DB_CHARSET', 'utf8');
define('DB_COLLATE', 'utf8_polish_ci');

Ältere MySQL-Version - utf8 und utf8_polish_ci . Neuere MySQL-Version - utf8mb4 und utf8mb4_polish_ci ( Suffix _polish_ci wird berücksichtigt )

define('DB_CHARSET', 'cp1250');
define('DB_COLLATE', 'cp1250_polish_ci');

Beliebige MySQL-Version - cp1250 und cp1250_polish_ci .

define('DB_CHARSET', 'cp1250');
define('DB_COLLATE', 'utf8_general_ci');

Beliebige MySQL-Version - Fehler (Nichtübereinstimmung von Zeichensatz und Sortierung)

Zusammenfassung

In den meisten Fällen ist es eine gute Wahl, die oben erläuterten Werte von Definitionen unverändert zu lassen. Wenn Sie jedoch möchten, dass die Tabellensortierung mit der Sprache Ihrer Website übereinstimmt, können Sie den Wert von DB_COLLATE define entsprechend ändern (z. B. utf8mb4_polish_ci ).

Hinweis: Dies erklärt, warum das Zeichen 𝌆 ordnungsgemäß gespeichert und abgerufen wurde. Ihr Tabellenzeichensatz gehörte einfach zur Gruppe utf8mb4 , nicht zu utf8 .

Frank P. Walentynowicz
quelle
1
Vielen Dank, dass Sie erklärt haben, wie Wordpress die Sortierung festlegt, aber Sie haben den Rest der Punkte nicht angesprochen. Warum zeigt MySQL, wenn der UTF-8-Zeichensatz definiert ist, die Datenbank als latin1 an? Und warum wird die Datenbankkollation als schwedisch angezeigt? Außerdem scheinen Sie Zeichensatz und Sortierung zu verwirren. Die Sortierung definiert nur die Reihenfolge und die Vergleichsregeln, nicht den Zeichensatz. Unabhängig davon, welche Kollatierung verwendet wird, sollten Zeichen außerhalb von UTF-8 (wie im engeren MySQL-Sinne definiert) nicht gerendert werden, wenn UTF-8 der Zeichensatz ist.
X-Mann
Ich werde meine Antwort aktualisieren, um den Prozess klarer zu erklären.
Frank P. Walentynowicz
1
Danke für das Update! Ich habe Ihre Antwort akzeptiert, jetzt ist alles klar. Das Problem liegt bei MySQL und meinem Mangel an Fachwissen - ich wusste nicht, dass Tabellen einen breiteren Zeichensatz als die Datenbank selbst verwenden können. Diese neuen Informationen haben mich beruhigt. Ich muss den Standardzeichensatz in MySQL nicht ändern, Wordpress kümmert sich auf Tabellenebene darum.
X-Mann
Bitte schön. Ich bin froh, dass es geholfen hat.
Frank P. Walentynowicz