Con el uso generalizado de varios conjuntos de caracteres multibyte, una proporción muy alta de programadores de habla inglesa en el desarrollo de software no saben mucho sobre los caracteres multibyte. Es por eso que muchas vulnerabilidades en los últimos años son multibyte. El autor de este artículo habla sobre sus propios puntos de vista sobre el papel de la arquitectura del juego de caracteres de MySQL. En los últimos meses, cada vez que uso MySQL, casi siempre pienso: ¿Es realmente útil la arquitectura jerárquica actual del juego de caracteres de MySQL?
Procesamiento del juego de caracteres MySQL
Enviar solicitud
Cliente (character_set_client)=》Conexión de base de datos (character_set_connection)=》Almacenamiento (tabla, columna)
solicitud de devolución
Almacenamiento (tabla, columna)=》Conexión de base de datos (character_set_connection)=》Cliente (character_set_results)
En cada nodo no inicial, se realiza una operación de conversión del juego de caracteres desde el nodo anterior al nodo actual. Por ejemplo, considere el siguiente entorno:
◆ carácter_set_conexión utf-8
◆ carácter_set_results gbk
◆ personaje_set_client gb2312
◆ Está la tabla A y los conjuntos de caracteres del campo son todos BIG5
Al enviar una solicitud, los datos primero se convierten de gbk a utf-8, luego a BIG5 y luego se almacenan.
Al devolver la solicitud, los datos primero se convierten de BIG5 a utf-8, luego a gb2312 y luego se envían al cliente.
El papel de la arquitectura.
1. Permita que diferentes clientes tengan diferentes conjuntos de caracteres. Un ejemplo típico es que tengo un sitio UTF-8, que es un cliente con un cliente de juego de caracteres de UTF-8. Al mismo tiempo, es posible que necesite leer y escribir la base de datos en un terminal gbk, que es otro cliente, pero su juego de caracteres es gbk.
2. Al operar el sistema de archivos a través de la base de datos, debe convertir la ruta del archivo al juego de caracteres del sistema de archivos. Por ejemplo, mi cliente es gbk y el sistema de archivos del servidor es utf-8. Operación "/A slice/Rina.rmvb", entre los datos enviados, los datos de "slice" son diferentes a los del servidor. En este momento, es necesario que haya una manera de convertir la "porción" de GBK a utf-8. Aquí MySQL introduce algo llamado caracter_filesystem para lograr esto.
Aparte de eso, no se me ocurre ningún otro uso por el momento. Pero piénselo bien, ¿realmente necesitamos este tipo de tratamiento? Muchos sitios web sólo esperan que sus datos salgan como quieran. Hay dos situaciones más aquí.
1. Espero poder ordenar o realizar operaciones similares basadas en los datos. Primero hablemos de ordenar. Para los campos que contienen chino, el concepto de ordenar según conjuntos de caracteres es inútil. Al ordenar chino simplificado, generalmente desea ordenar por Pinyin. Realmente no entiendo la verificación en MySQL, pero a juzgar por los programas con los que he entrado en contacto, si se requiere este tipo de clasificación, se crea un campo especialmente para almacenar pinyin para la clasificación. También hay caracteres polifónicos en Pinyin. Si es UTF-8, también existe una situación en la que China, Japón y Corea del Sur comparten un cierto rango de chinos al mismo tiempo. No es tan fácil de implementar, por lo que ni GBK ni el conjunto de verificación UTF-8 de MySQL deberían implementar Pinyin. Me atrevo a decir que la mayoría de los sitios web en China que usan MySQL ahora usan un conjunto de verificación que es solo una clasificación de bytes. Con la clasificación de bytes, no es necesario utilizar ningún juego de caracteres. Por lo tanto, para los sitios chinos, la verificación de caracteres MySQL no tiene sentido en la clasificación.
Pero en términos de operación similar, tiene un pequeño significado. Por ejemplo, si me gusta '%a%', es posible hacer coincidir un carácter chino que contenga a en una parte determinada. Por supuesto, esta situación no se encontrará en UTF-8, porque el formato de almacenamiento de UTF-8 significa que a solo puede ser a y no puede ser parte de un carácter de varios bytes. Pero este problema puede ocurrir en otros conjuntos de caracteres. Al final, lo similar se convierte en lo mismo que el orden, lo que hace que la verificación carezca de sentido. débil.
2. Si no es necesario ordenar los datos, como me gusta o buscar texto completo, deje de usar char, varchar, text y similares. binario, varbinary, BLOB son las opciones correctas. Los binarios y similares no realizarán la conversión del juego de caracteres al almacenar y recuperar, pero al ordenar, solo se clasifican según el contenido binario, por lo que la eficiencia es mucho mayor que la de char, varchar y text.
En este caso, no es necesario ningún juego de caracteres. Sin embargo, de acuerdo con la arquitectura MySQL actual, las operaciones de juego de caracteres entre el cliente y la conexión ignoran los tipos de campos se seguirán realizando entre estos dos nodos.
También mencione la configuración del juego de caracteres en PHP. Deje de usar declaraciones como mysql_query ("establecer nombres utf8"). mysql_set_charset() es el método de configuración de juegos de caracteres más completo. Este último tiene una configuración más que el primero, que consiste en configurar el miembro del conjunto de caracteres de la estructura MySQL. Esta variable miembro juega un papel muy importante en el escape, especialmente para formatos de codificación como GBK que usan "" como parte del carácter. Si solo usa mysql_query ("establecer nombres XXX"), en algunos conjuntos de caracteres, habrá importantes agujeros de seguridad, lo que hará que mysql_real_escape_string se vuelva tan inseguro como addlashes.
-