Masalah ini mengganggu peserta situs ini, dan banyak lainnya.
Anda telah membuat daftar lima kasus utama CHARACTER SET
masalah.
Praktik Terbaik
Ke depan, sebaiknya gunakan CHARACTER SET utf8mb4
dan COLLATION utf8mb4_unicode_520_ci
. (Ada versi terbaru dari susunan Unicode dalam proses.)
utf8mb4
adalah superset dari utf8
karena menangani kode utf8 4-byte, yang dibutuhkan oleh Emoji dan beberapa orang Cina.
Di luar MySQL, "UTF-8" mengacu pada semua ukuran encoding, maka secara efektif sama dengan utf8mb4
MySQL , bukan utf8
.
Saya akan mencoba menggunakan ejaan dan huruf besar tersebut untuk membedakan di dalam dan di luar MySQL berikut ini.
Ikhtisar tentang apa yang seharusnya lakukan
- Setel editor Anda, dll. ke UTF-8.
- Formulir HTML harus dimulai seperti
<form accept-charset="UTF-8">
. - Membuat byte Anda dikodekan sebagai UTF-8.
- Tetapkan UTF-8 sebagai pengkodean yang digunakan di klien.
- Suruh kolom/tabel dideklarasikan
CHARACTER SET utf8mb4
(Periksa denganSHOW CREATE TABLE
.) <meta charset=UTF-8>
di awal HTML- Rutinitas Tersimpan memperoleh rangkaian karakter/penyusunan saat ini. Mereka mungkin perlu dibangun kembali.
Detail lebih lanjut untuk bahasa komputer (dan bagian berikutnya)
Uji data
Melihat data dengan alat atau dengan SELECT
tidak dapat dipercaya. Terlalu banyak klien seperti itu, terutama browser, mencoba untuk mengkompensasi penyandian yang salah, dan menunjukkan teks yang benar meskipun databasenya rusak. Jadi, pilih tabel dan kolom yang memiliki teks non-Inggris dan lakukan
SELECT col, HEX(col) FROM tbl WHERE ...
HEX untuk UTF-8 yang disimpan dengan benar adalah
- Untuk ruang kosong (dalam bahasa apapun):
20
- Untuk bahasa Inggris:
4x
,5x
,6x
, atau7x
- Untuk sebagian besar Eropa Barat, huruf beraksen harus
Cxyy
- Sirilik, Ibrani, dan Farsi/Arab:
Dxyy
- Sebagian besar Asia:
Exyyzz
- Emoji dan beberapa bahasa Mandarin:
F0yyzzww
- Detail selengkapnya
Penyebab dan perbaikan khusus dari masalah yang terlihat
Terpotong teks (Se
untuk Señor
):
- Byte yang akan disimpan tidak dikodekan sebagai utf8mb4. Perbaiki ini.
- Juga, periksa apakah koneksi selama membaca adalah UTF-8.
Berlian Hitam dengan tanda tanya (Se�or
untuk Señor
);salah satu dari kasus ini ada:
Kasus 1 (byte asli tidak UTF-8):
- Byte yang akan disimpan tidak dikodekan sebagai utf8. Perbaiki ini.
- Koneksi (atau
SET NAMES
) untukINSERT
danSELECT
bukan utf8/utf8mb4. Perbaiki ini. - Juga, periksa apakah kolom dalam database adalah
CHARACTER SET utf8
(atau utf8mb4).
Kasus 2 (byte asli adalah UTF-8):
- Koneksi (atau
SET NAMES
) untukSELECT
bukan utf8/utf8mb4. Perbaiki ini. - Juga, periksa apakah kolom dalam database adalah
CHARACTER SET utf8
(atau utf8mb4).
Berlian hitam hanya muncul jika browser disetel ke <meta charset=UTF-8>
.
Tanda Tanya (yang biasa, bukan berlian hitam) (Se?or
untuk Señor
):
- Byte yang akan disimpan tidak dikodekan sebagai utf8/utf8mb4. Perbaiki ini.
- Kolom dalam database bukan
CHARACTER SET utf8
(atau utf8mb4). Perbaiki ini. (GunakanSHOW CREATE TABLE
.) - Juga, periksa apakah koneksi selama membaca adalah UTF-8.
Mojibake (Señor
untuk Señor
):(Diskusi ini juga berlaku untuk Pengkodean Ganda , yang belum tentu terlihat.)
- Byte yang akan disimpan harus dienkode UTF-8. Perbaiki ini.
- Koneksi saat
INSERTing
danSELECTing
teks perlu menentukan utf8 atau utf8mb4. Perbaiki ini. - Kolom harus dideklarasikan
CHARACTER SET utf8
(atau utf8mb4). Perbaiki ini. - HTML harus dimulai dengan
<meta charset=UTF-8>
.
Jika data terlihat benar, tetapi tidak mengurutkan dengan benar, maka Anda telah memilih susunan yang salah, atau tidak ada susunan yang sesuai dengan kebutuhan Anda, atau Anda memiliki Pengkodean Ganda .
Pengkodean Ganda dapat dikonfirmasi dengan melakukan SELECT .. HEX ..
dijelaskan di atas.
é should come back C3A9, but instead shows C383C2A9
The Emoji 👽 should come back F09F91BD, but comes back C3B0C5B8E28098C2BD
Artinya, hex sekitar dua kali lebih panjang dari yang seharusnya. Ini disebabkan oleh konversi dari latin1 (atau apa pun) ke utf8, kemudian memperlakukan byte tersebut seolah-olah mereka latin1 dan mengulangi konversi. Penyortiran (dan perbandingan) tidak bekerja dengan benar karena, misalnya, mengurutkan seolah-olah string adalah Señor
.
Memperbaiki Data, jika memungkinkan
Untuk Pemotongan dan Tanda Tanya , datanya hilang.
Untuk Mojibake / Pengkodean Ganda , ...
Untuk Berlian Hitam , ...
Perbaikan tercantum di sini. (5 perbaikan berbeda untuk 5 situasi berbeda; pilih dengan hati-hati):http://mysql. rjweb.org/doc.php/charcoll#fixes_for_various_cases