Dengan meluasnya penggunaan berbagai kumpulan karakter multi-byte, sebagian besar pemrogram berbahasa Inggris dalam pengembangan perangkat lunak tidak mengetahui banyak tentang karakter multi-byte. Inilah sebabnya mengapa banyak kerentanan dalam beberapa tahun terakhir adalah penyebabnya. Penulis artikel ini berbicara tentang pandangannya sendiri tentang peran arsitektur himpunan karakter MySQL. Dalam beberapa bulan terakhir, setiap kali saya menggunakan MySQL, saya hampir selalu berpikir: Apakah arsitektur rangkaian karakter hierarki MySQL saat ini benar-benar berguna?
Pemrosesan set karakter MySQL
Kirim permintaan
Klien (character_set_client)=》Koneksi database (character_set_connection)=》Penyimpanan (tabel, kolom)
permintaan pengembalian
Penyimpanan (tabel, kolom)=》Koneksi database (character_set_connection)=》Klien (character_set_results)
Pada setiap node non-awal, operasi konversi kumpulan karakter dilakukan dari node sebelumnya ke node saat ini. Misalnya, pertimbangkan lingkungan berikut:
◆ karakter_set_koneksi utf-8
◆ character_set_results gbk
◆ character_set_client gb2312
◆ Ada tabel A, dan kumpulan karakter bidang semuanya BIG5
Saat mengirim permintaan, data diubah terlebih dahulu dari gbk ke utf-8, lalu ke BIG5, lalu disimpan.
Saat mengembalikan permintaan, data dikonversi terlebih dahulu dari BIG5 ke utf-8, kemudian ke gb2312, dan kemudian dikirim ke klien.
Peran arsitektur
1. Izinkan klien yang berbeda memiliki rangkaian karakter yang berbeda. Contoh umumnya adalah saya memiliki situs UTF-8, yang merupakan klien dengan klien charset UTF-8. Pada saat yang sama, saya mungkin perlu membaca dan menulis database di terminal gbk, yang merupakan klien lain, tetapi rangkaian karakternya adalah gbk.
2. Saat mengoperasikan sistem file melalui database, Anda perlu mengonversi jalur file ke kumpulan karakter sistem file. Misalnya klien saya adalah gbk dan sistem file server adalah utf-8. Operasi "/A slice/Rina.rmvb", di antara data yang dikirim, data "slice" berbeda dari server. Saat ini, perlu ada cara untuk mengubah "slice" GBK menjadi utf-8. Di sini MySQL memperkenalkan sesuatu yang disebut character_filesystem untuk mencapai hal ini.
Selain itu, saya tidak bisa memikirkan kegunaan lain untuk saat ini. Namun coba pikirkan baik-baik, apakah kita memang membutuhkan pengobatan seperti ini? Banyak website yang hanya berharap datanya bisa keluar sesuka hati. Ada dua situasi lagi di sini.
1. Saya harap saya dapat mengurutkan atau melakukan operasi serupa berdasarkan data. Mari kita bicara tentang pengurutan terlebih dahulu. Untuk bidang yang berisi bahasa Mandarin, konsep pengurutan berdasarkan rangkaian karakter tidak ada gunanya. Saat mengurutkan bahasa Mandarin Sederhana, biasanya Anda ingin mengurutkan berdasarkan Pinyin. Saya belum begitu memahami verifikasi di MySQL, tetapi dilihat dari program yang pernah saya gunakan, jika penyortiran jenis ini diperlukan, sebuah kolom dibuat khusus untuk menyimpan pinyin untuk penyortiran. Ada juga karakter polifonik di Pinyin. Jika UTF-8, ada juga situasi di mana sejumlah bahasa Tionghoa dimiliki oleh Tiongkok, Jepang, dan Korea Selatan pada saat yang bersamaan. Implementasinya tidak mudah, jadi baik GBK maupun checkset UTF-8 MySQL tidak boleh mengimplementasikan Pinyin. Saya berani mengatakan bahwa sebagian besar situs web di China yang menggunakan MySQL sekarang menggunakan set centang yang hanya berupa pengurutan byte. Dengan penyortiran byte, tidak perlu menggunakan kumpulan karakter apa pun sama sekali. Oleh karena itu, untuk situs China, verifikasi karakter MySQL tidak ada artinya dalam penyortiran.
Namun dalam hal pengoperasian serupa, ini memang memiliki sedikit arti. Misalnya, jika saya menyukai '%a%', saya dapat mencocokkan karakter Cina yang mengandung a di bagian tertentu. Tentu saja, situasi ini tidak akan ditemui pada UTF-8, karena format penyimpanan UTF-8 berarti a hanya dapat berupa a, dan tidak dapat menjadi bagian dari karakter multi-byte. Namun masalah ini mungkin terjadi pada rangkaian karakter lain. Pada akhirnya, suka menjadi sama dengan pesanan, membuat verifikasi menjadi tidak ada artinya. pingsan.
2. Jika tidak perlu mengurutkan data, suka atau pencarian teks lengkap, silakan berhenti menggunakan char, varchar, teks dan sejenisnya. biner, varbinary, BLOB adalah pilihan yang tepat. Biner dan sejenisnya tidak akan melakukan konversi kumpulan karakter saat menyimpan dan mengambil, tetapi saat mengurutkan, mereka hanya diurutkan berdasarkan konten biner, sehingga efisiensinya jauh lebih tinggi daripada char, varchar, dan teks.
Dalam hal ini, tidak diperlukan kumpulan karakter. Namun, menurut arsitektur MySQL saat ini, operasi kumpulan karakter antara klien dan koneksi mengabaikan jenis bidang. Konversi kumpulan karakter akan tetap dilakukan antara dua node ini.
Sebutkan juga pengaturan set karakter di PHP. Harap berhenti menggunakan pernyataan seperti mysql_query("set nama utf8"). mysql_set_charset() adalah metode pengaturan kumpulan karakter terlengkap. Yang terakhir memiliki satu pengaturan lebih dari yang pertama, yaitu mengatur anggota charset dari struct MySQL. Variabel anggota ini memainkan peran yang sangat penting dalam escape, terutama untuk format pengkodean seperti GBK yang menggunakan "" sebagai bagian dari karakternya. Jika Anda hanya menggunakan mysql_query("set nama XXX"), maka di beberapa rangkaian karakter, akan ada lubang keamanan besar, menyebabkan mysql_real_escape_string menjadi tidak aman seperti addlashes.
-