Avec l'utilisation généralisée de divers jeux de caractères multi-octets, une très forte proportion de programmeurs anglophones dans le développement de logiciels ne connaissent pas grand-chose aux caractères multi-octets. C'est pourquoi de nombreuses vulnérabilités de ces dernières années sont dues au multi-octet. L'auteur de cet article parle de son propre point de vue sur le rôle de l'architecture des jeux de caractères de MySQL. Au cours des derniers mois, chaque fois que j'utilise MySQL, je pense presque toujours : l'architecture hiérarchique actuelle des jeux de caractères de MySQL est-elle vraiment utile ?
Traitement du jeu de caractères MySQL
Envoyer la demande
Client (character_set_client)=》Connexion à la base de données (character_set_connection)=》Stockage (table, colonne)
demande de retour
Stockage (table, colonne)=》Connexion à la base de données (character_set_connection)=》Client (character_set_results)
Au niveau de chaque nœud non initial, une opération de conversion de jeu de caractères est effectuée du nœud précédent vers le nœud actuel. Par exemple, considérons l'environnement suivant :
◆ caractère_set_connection utf-8
◆ caractère_set_results gbk
◆ caractère_set_client gb2312
◆ Il existe le tableau A et les jeux de caractères des champs sont tous BIG5
Lors de l'envoi d'une requête, les données sont d'abord converties de gbk en utf-8, puis en BIG5, puis stockées.
Lors du renvoi de la demande, les données sont d'abord converties de BIG5 en utf-8, puis en gb2312, puis envoyées au client.
Le rôle de l'architecture
1. Autorisez différents clients à avoir des jeux de caractères différents. Un exemple typique est que j'ai un site UTF-8, qui est un client avec un jeu de caractères UTF-8. En même temps, je devrai peut-être lire et écrire la base de données sur un terminal gbk, qui est un autre client, mais son jeu de caractères est gbk.
2. Lorsque vous utilisez le système de fichiers via la base de données, vous devez convertir le chemin du fichier en jeu de caractères du système de fichiers. Par exemple, mon client est gbk et le système de fichiers du serveur est utf-8. Opération "/A slice/Rina.rmvb", parmi les données envoyées, les données de "slice" sont différentes de celles du serveur. À l’heure actuelle, il doit y avoir un moyen de convertir la « tranche » de GBK en utf-8. Ici, MySQL introduit quelque chose appelé Character_filesystem pour y parvenir.
A part ça, je ne vois pas d'autres utilisations pour le moment. Mais réfléchissez bien : avons-nous vraiment besoin de ce type de traitement ? De nombreux sites Web espèrent simplement que leurs données pourront être publiées à leur guise. Il y a deux autres situations ici.
1. J'espère pouvoir trier ou effectuer des opérations similaires en fonction des données. Parlons d'abord du tri. Pour les champs contenant du chinois, le concept de tri basé sur les jeux de caractères est inutile. Lors du tri du chinois simplifié, vous souhaitez généralement trier par Pinyin. Je n'ai pas vraiment compris la vérification dans MySQL, mais à en juger par les programmes avec lesquels j'ai été en contact, si ce type de tri est requis, un champ est spécialement créé pour stocker le pinyin à trier. Il existe également des caractères polyphoniques en Pinyin. S'il s'agit d'UTF-8, il existe également une situation dans laquelle une certaine gamme de chinois est partagée en même temps par la Chine, le Japon et la Corée du Sud. Ce n'est pas si facile à implémenter, donc ni le GBK ni le jeu de contrôle UTF-8 de MySQL ne devraient implémenter le Pinyin. J'ose dire que la plupart des sites Web en Chine qui utilisent MySQL utilisent désormais un jeu de contrôle qui n'est qu'un tri par octets. Avec le tri par octets, il n’est pas nécessaire d’utiliser un jeu de caractères. Par conséquent, pour les sites chinois, la vérification des caractères MySQL n'a aucune signification dans le tri.
Mais en termes de fonctionnement similaire, cela a un peu de sens. Par exemple, si j'aime '%a%', il est possible de faire correspondre un caractère chinois contenant un dans une certaine partie. Bien entendu, cette situation ne se produira pas sous UTF-8, car le format de stockage d'UTF-8 signifie que a ne peut être qu'un et ne peut pas faire partie d'un caractère multi-octets. Mais ce problème peut survenir dans d’autres jeux de caractères. En fin de compte, le semblable devient l’équivalent de l’ordre, rendant la vérification dénuée de sens. s'évanouir.
2. S'il n'est pas nécessaire de trier les données, de rechercher des likes ou de rechercher du texte intégral, arrêtez d'utiliser char, varchar, text, etc. binaire, varbinaire, BLOB sont les bons choix. Les binaires et autres n'effectueront pas de conversion de jeu de caractères lors du stockage et de la récupération, mais lors du tri, ils ne sont triés qu'en fonction du contenu binaire, de sorte que l'efficacité est bien supérieure à celle de char, varchar et text.
Dans ce cas, aucun jeu de caractères n’est nécessaire. Cependant, selon l'architecture MySQL actuelle, les opérations de jeu de caractères entre les types de champs ignorés du client et de la connexion seront toujours effectuées entre ces deux nœuds.
Mentionnez également le paramètre de jeu de caractères en PHP. Veuillez cesser d'utiliser des instructions telles que mysql_query("set names utf8"). mysql_set_charset() est la méthode de définition de jeu de caractères la plus complète. Ce dernier a un paramètre de plus que le premier, qui consiste à définir le membre charset de la structure MySQL. Cette variable membre joue un rôle très important dans l'échappement, en particulier pour les formats d'encodage tels que GBK qui utilisent "" dans le cadre du caractère. Si vous utilisez uniquement mysql_query("set names XXX"), alors dans certains jeux de caractères, il y aura des failles de sécurité majeures, rendant mysql_real_escape_string aussi dangereux que les addlashes.
-