Si l'utilisation de “NOMS”
Dans la lecture de "Haute performance MySQL" de O'Reilly, j'ai trébuché sur la suite de
Une autre poubelle commune requête est DÉFINIE
Les NOMS de l'utf-8, qui est la mauvaise façon de
faire les choses de toute façon (il ne change pas
la bibliothèque client du jeu de caractères; il
affecte uniquement le serveur).
Je suis un peu confus, parce que j'ai utilisé pour mettre "SET NAMES utf8" dans le haut de chaque script de laisser la db sais que mes questions sont encodés en utf-8.
Quelqu'un peut-il commenter la citation ci-dessus, ou, pour le dire de façon plus formelle, quelles sont vos suggestions /les meilleures pratiques pour s'assurer que ma base de données de flux de travail est compatible avec unicode.
Mes langues cibles sont le php et python, si cela est pertinent.
- quelle technique avez-vous en fin de mise en œuvre?
Vous devez vous connecter pour publier un commentaire.
mysql_set_charset()
serait une option, mais une option limitée à laext/mysql
. Pourext/mysqli
il estmysqli_set_charset
et pourPDO
::mysql
vous devez spécifier un paramètre de connexion.Que l'utilisation de cette fonction entraîne une API MySQL appel, il doit être considéré comme beaucoup plus rapide que l'émission d'une requête.
À l'égard de la performance le moyen le plus rapide pour assurer un UTF-8 communiction entre votre script et le serveur MySQL est la configuration du serveur MySQL correctement. Comme
SET NAMES x
est équivalent àalors que
SET character_set_connection = x
en interne exécute égalementSET collation_connection = <<default_collation_of_character_set_x>>
vous pouvez également définir ces variables de serveur de façon statique dans votremy.ini/cnf
.S'il vous plaît être conscient des problèmes éventuels avec d'autres applications en cours d'exécution sur la même instance de serveur MySQL et nécessitant un autre jeu de caractères.
mysql_set_charset()
- c'est une fonction incluse dans la vieilleext/mysql
. Comme indiqué ci-dessus, niPDO
niext/mysqli
fournir un soutien pour cette opération directement.mysqli_set_charset
fonction disponible. Merci pour la clarification.TLDR
Cette réponse met l'accent sur le php pdo bibliothèque parce que c'est tellement omniprésent.
Un bref rappel - mysql est une architecture client-serveur. Ceci est important car il n'y a pas seulement le serveur mysql où la base de données actuelle est, mais il y a aussi de différentes client mysql pilote, ce qui est la chose que les pourparlers sur le serveur mysql(ils sont des entités distinctes). Vous pourriez un peu sorta dire le client mysql et pdo sont mélangées.
Lorsque vous utilisez
set names utf8
, vous émettez une requête sql standard de mysql. Alors que la requête sql ne passer par pdo, et ensuite à travers la bibliothèque cliente mysql, et puis, finalement, il atteint le serveur mysql, SEUL le serveur mysql analyse et interprète la requête sql. Ceci est important parce que le serveur mysql ne pas envoyer de message à pdo ou le client mysql laisser connaître le jeu de caractères et encodage a changé, et donc le client mysql et pdo sont à la fois totalement ignorants du fait qu'il s'est passé.Il est important de ne pas effectuer cette opération car le client de la bibliothèque ne peut pas gérer correctement les chaînes si elle n'est pas au courant de la jeu de caractères. La plupart des opérations courantes fonctionnera correctement sans que le client de connaître le jeu de caractères correct, mais qui ne l'est l'échappement de la chaîne, comme PDO::quote. Vous pouvez penser que vous n'avez pas besoin de s'inquiéter à propos de ce manuel primitive de la chaîne d'échapper, parce que vous utilisez déclarations préparées à l'avance, mais la vérité est que la grande majorité des pdo:mysql les utilisateurs sans le savoir l'utilisation des émules déclarations préparées à l'avance parce que c'est le paramètre par défaut pour la pdo:pilote mysql pour un temps très long maintenant. Un émulé instruction préparée, ne pas utiliser de vrais natif mysql préparé des déclarations fournies par l'api mysql; au lieu de cela, php ne l'équivalent d'appeler
PDO::quote()
sur tous vos valeurs, et str_replacing avec tous vos espaces réservés à la cité des valeurs pour vous.Puisque vous ne pouvez pas échapper correctement une chaîne de caractères, sauf si vous savez le jeu de caractères que vous utilisez, ces émulé préparées sont vulnérables à l'injection sql, si vous avez modifié à certains jeux de caractères via
set names
. Indépendamment de la question de l'injection sql, vous pouvez toujours briser vos chaînes si vous utilisez un échapper régime destiné à un jeu de caractères différent.Pour le pilote pdo mysql, vous pouvez spécifier le jeu de caractères lorsque vous vous connectez, par le précisant dans la DSN. La bibliothèque client et le serveur sera à la fois être conscient du jeu de caractères si vous le faites, et si les choses vont fonctionner comme ils le devraient.
Impropre mais l'échappement de la chaîne n'est pas le seul problème. Par exemple, vous pouvez également avoir des problèmes avec l'aide de PDO::bindColumn parce que les noms de colonnes sont spécifiées comme des chaînes de caractères, et de nouveau le codage des questions. Un exemple pourrait être un nom de colonne nommée
ütube
(notez le tréma), et vous passez delatin
àutf8
jeu par le biais des noms, et puis vous essayez de$stmt->bindColumn('ütube', $var);
avecütube
être encodés en utf-8 en chaîne, car votre fichier php est encodés en utf-8. Elle ne fonctionne pas, vous devrez encoder la chaîne comme un latin1 variante... et maintenant, vous avez toutes sortes de folie.Pas sûr au sujet de py, mais php a
mysql_set_charset
maintenant, qui stipule que c'est la "meilleure façon de modifier le jeu de caractères [et] à l'aide de mysql_query() pour exécuter le nom du SET n'est pas recommandé." Notez que cette fonction a été introduite pour MySQL 5.0.7, donc il ne fonctionnera pas avec les versions antérieures.Où $lien est un lien créé avec
mysql_connect