Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

data utf8 terlihat baik-baik saja di mysql tetapi rusak di Rails

Ketika klien MySQL berinteraksi dengan server:

  1. server menerima teks apa pun hanya sebagai string byte; klien sebelumnya akan memberitahunya bagaimana teks tersebut akan dikodekan.

  2. jika server kemudian harus menyimpan teks itu dalam sebuah tabel, itu harus mentranskodekannya ke pengkodean kolom yang relevan (jika berbeda).

  3. jika klien kemudian ingin mengambil teks tersebut, server harus mentranskodekannya ke pengkodean yang diharapkan oleh klien.

Jika penyandian yang digunakan oleh klien pada langkah 1 dan 3 sama (yang biasanya terjadi, terutama ketika klien dalam kedua kasus adalah aplikasi yang sama), maka sering kali tidak diperhatikan jika klien menggunakan pengkodean selain yang dikatakannya. Misalnya, klien memberi tahu MySQL bahwa ia akan menggunakan latin1 , tetapi sebenarnya mengirimkan data dalam utf8 :

  • String 'Jazz–Man' dikirim ke server dalam UTF-8 sebagai 0x4a617a7ae280934d616e .

  • MySQL, mendekode byte tersebut di Windows-1252, memahaminya untuk mewakili string 'Jazz–Man' .

  • Untuk menyimpan dalam utf8 kolom, MySQL mentranskode string ke penyandian UTF-8 0x4a617a7ac3a2e282ace2809c4d616e . Ini dapat diverifikasi dengan menggunakan SELECT HEX(name) FROM lessons WHERE id=79510 .

  • Ketika klien mengambil nilainya, MySQL berpikir bahwa ia menginginkannya dalam latin1 dan transcode ke Windows-1252 encoding 0x4a617a7ae280934d616e .

  • Saat klien menerima byte tersebut, ia mendekodekannya sebagai UTF-8 dan oleh karena itu memahami string tersebut sebagai 'Jazz–Man' .

Kesimpulan :klien tidak menyadari ada yang salah. Masalah hanya terdeteksi saat klien berbeda (klien yang tidak salah menyatakan koneksi UTF-8 sebagai latin1 ) mencoba menggunakan tabel. Dalam kasus Anda, ini terjadi ketika mysqldump memperoleh ekspor data; menggunakan --default-character-set=latin1 --skip-set-charset options secara efektif memaksa mysqldump untuk berperilaku dengan cara yang sama seperti aplikasi Anda, sehingga berakhir dengan data yang dikodekan dengan benar.

Untuk memperbaiki masalah Anda di masa mendatang, Anda harus:

  1. Konfigurasikan aplikasi Anda sehingga set karakter koneksi MySQL dengan benar (mis. set encoding: utf8 di config/database.yml untuk Rel);

  2. Kode ulang data dalam database Anda, mis. UPDATE lessons SET name = BINARY CONVERT(name USING latin1) (perhatikan bahwa ini harus dilakukan untuk setiap kolom teks yang salah kodenya).

Perhatikan juga bahwa Anda mungkin ingin melakukan dua tindakan ini secara atom, yang mungkin memerlukan pemikiran.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nilai peningkatan otomatis yang ketat di MySQL

  2. menggunakan buruh pelabuhan --link ke mysql

  3. Memasukkan record ke dalam tabel MySQL menggunakan Java

  4. Kutipan Tunggal MySQL, Kutipan Ganda, Kutipan Kembali Dijelaskan Penggunaannya

  5. Variabel mendapatkan NULL setelah perhitungan di MySQL Trigger