Tolong jelaskan bagaimana Wordpress bekerja dengan set dan collation karakter MySQL pada level rendah

10

Seperti yang disarankan judul pertanyaan, saya ingin memahami bagaimana Wordpress bekerja dengan set karakter MySQL dan opsi pengumpulan. Seperti yang akan saya tunjukkan di bawah, hal-hal yang tidak masuk akal bagi saya ...

Saya menginstal Wordpress dengan mengikuti instruksi pada halaman instalasi mereka:

https://codex.wordpress.org/Installing_WordPress

Sebagai bagian dari instruksi, saya mengikuti saran mereka untuk pembuatan manual dari database MySQL pada commandline, yaitu perintah:

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

Selanjutnya, seperti yang diinstruksikan, saya mengedit file "wp-config.php" untuk menggunakan set karakter UTF-8:

define( 'DB_CHARSET', 'utf8' );

... dan biarkan pengaturan pemeriksaan kosong:

define( 'DB_COLLATE', '' );

Di sinilah kesenangan dimulai ...

  1. Jika saya memasukkan karakter yang bukan merupakan bagian dari MySQL UTF-8, tetapi merupakan bagian dari UTF-8 MB4, seperti 𝌆, ke dalam sebuah postingan, itu akan ditampilkan dengan benar di halaman yang diberikan. Saya akan berharap ini tidak terjadi, karena saya belum menetapkan karakter yang ditetapkan ke UTF-8 MB4, tetapi UTF-8 lebih terbatas (seperti yang didefinisikan oleh MySQL tentu saja, tidak seperti yang dipahami secara umum).

  2. Jika saya menyelidiki masalah di MySQL pada commandline, itu akan lebih aneh. Jika saya lari show variables like 'char%';, saya mendapat respons ini:

    +--------------------------+----------------------------+
    | 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/ |
    +--------------------------+----------------------------+

Saya akan mengharapkan karakter basis data ditetapkan menjadi UTF-8, bukan latin1.

  1. Jika saya menjalankan perintah show variables like 'collation%';, hasilnya adalah:

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

Itu bahkan lebih aneh, untuk alasan yang jelas (tidak akan mengharapkan pemeriksaan latin1_swedish_ci default dalam database UTF-8).

  1. Akhirnya, jika saya menjalankan show full columns from mywpdatabase.wp_posts;, garis output, di mana nilainya bukan NULL, tampilkan collation menjadi:

| post_content_filtered | longtext | utf8mb4_unicode_ci |

Pertanyaan saya kemudian - bagaimana ini bisa dijelaskan? Mengapa Wordpress saya menginstal dengan benar memberikan karakter UTF-8 MB4, ketika database didefinisikan sebagai UTF-8 dalam konfigurasi? Dan mengapa database ditampilkan di MySQL sebagai latin1, collation swedia, bukan UTF-8? Dan mengapa, terlepas dari semua ini, masing-masing bidang dalam tabel adalah utf8mb4_unicode_ci? Penjelasan tingkat rendah tentang cara Wordpress bekerja dengan MySQL akan sangat membantu. Terima kasih!

X-Mann
sumber

Jawaban:

11

Ada dua definisi di wp-config.php dari situs WordPress:

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

Ada beberapa hal yang paling sering disalahpahami. Nama konstanta dalam definisi tersebut, mungkin menyarankan bahwa mereka terkait dengan database itu sendiri. Mereka tidak. Mereka terkait dengan tabel dalam database.

Pembuatan basis data benar-benar independen dari pembuatan tabel. WordPress tidak membuat database dan tidak peduli dengan set karakter standar dan collation, asalkan dapat terhubung ke database.

Nilai 'utf8' dalam definisi pertama berarti, karakter paling tidak terbatas yang ditetapkan dari keluarga 'utf8', yang dapat berupa 'utf8' atau 'utf8mb4'.

Jika Anda membiarkan definisi di atas tidak berubah, sebelum upaya untuk menginstal situs web Anda, itu seperti memberi tahu WordPress untuk membuat pilihan sendiri, mengenai kumpulan dan kumpulan karakter tabel database, yang didukung oleh MySQL (tergantung versi MySQL) dan paling tidak membatasi.

Berikut ini adalah hal-hal, analisis WordPress untuk menentukan pilihannya, selama instalasi:

  • Versi MySQL
  • pengumpulan basis data (di wp-config.php)

Berdasarkan versi MySQL, WordPress memutuskan, kelompok keluarga utf8 mana yang akan digunakan. Ada dua, dibedakan dengan namanya: utf8 dan utf8mb4 . Set karakter dari grup utf8 , memungkinkan penyimpanan karakter maksimal 3-byte. Set karakter dari grup utf8mb4 , memungkinkan penyimpanan karakter maksimum 4-byte.

Sekarang, WordPress memeriksa nilai dari definisi DB_COLLATE . Jika kosong, itu akan menggunakan collation paling membatasi dari keluarga utf8 yang dipilih , jika tidak, akan menggunakan nilai yang ditentukan.

Contohnya

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

Jika MySQL tidak mendukung utf8mb4 (versi yang lebih lama) maka set karakter tabel akan utf8 dan collation akan menjadi utf8_general_ci . Kalau tidak, kita dapat mengharapkan utf8mb4 dan utf8mb4_unicode_520_ci , atau utf8mb4_unicode_ci (tergantung versi MySQL).

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

Versi MySQL yang lebih lama - utf8 dan utf8_polish_ci . Versi MySQL yang lebih baru - utf8mb4 dan utf8mb4_polish_ci ( sufiks _polish_ci dihormati)

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

Setiap versi MySQL - cp1250 dan cp1250_polish_ci .

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

Apa saja versi MySQL - kesalahan (ketidakcocokan set karakter dan susunan)

Ringkasan

Dalam kebanyakan kasus, membiarkan nilai-nilai definisi, yang dijelaskan di atas, tidak berubah, adalah pilihan yang baik. Tetapi, jika Anda ingin susunan tabel agar sesuai dengan bahasa situs web Anda, Anda dapat memodifikasi nilai DB_COLLATE define, secara tepat (misalnya - utf8mb4_polish_ci ).

Catatan: itu menjelaskan, mengapa karakter 𝌆 disimpan dan diambil dengan benar. Sederhananya, set karakter tabel Anda milik grup utf8mb4 , bukan utf8 .

Frank P. Walentynowicz
sumber
1
Terima kasih telah menjelaskan bagaimana Wordpress mengatur susunan, tetapi Anda belum membahas sisa poin. Mengapa, jika set karakter UTF-8 didefinisikan, apakah MySQL menunjukkan database sebagai latin1? Dan mengapa ini menunjukkan collation database sebagai swedia? Selain itu, Anda tampaknya membingungkan kumpulan dan susunan karakter. Collation hanya mendefinisikan pemesanan, aturan perbandingan, bukan set karakter. Oleh karena itu, tidak peduli apa susunan yang digunakan, jika UTF-8 adalah set karakter, karakter di luarnya (sebagaimana didefinisikan dalam pengertian MySQL yang lebih sempit) tidak boleh di-render.
X-Mann
Saya akan memperbarui jawaban saya, untuk menjelaskan prosesnya dengan lebih jelas.
Frank P. Walentynowicz
1
Terima kasih atas pembaruannya! Saya telah menerima jawaban Anda, semuanya jelas sekarang. Masalahnya adalah dengan MySQL dan kurangnya keahlian saya di dalamnya - saya tidak tahu tabel dapat menggunakan set karakter yang lebih luas daripada database itu sendiri. Info baru ini telah membuat pikiran saya nyaman. Saya tidak perlu mengubah set karakter default di MySQL, Wordpress menanganinya di tingkat tabel.
X-Mann
Sama sama. Saya senang itu membantu.
Frank P. Walentynowicz