[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [hs] MySQL : utf8_general_ci ou utf8_unicode_ci ou utf8mb4_unicode_ci



Le 30/01/17 à 14:55, Dominique Asselineau <asseline@telecom-paristech.fr> a écrit :
DA> Bonjour et merci de ces précisions.
DA> 
DA> Le contexte serait un peu plus large que le français mais ça resterait
DA> parmi les langues européennes.  Dans ce cas utf8mb4_general_ci
DA> serait-il toujours performant ?

Que veux-tu dire par performant ?

Si tu parle de la rapidité d'une application qui utiliserait une base mysql, je doute que le
changement de charset / collation soit perceptible.

Donc réponse courte :
- si c'est une appli web, prend le charset de tes pages web et du langage que tu utilises
  (utf8mb4_ est plus conforme à la norme, mais utf8_ reste un choix pertinent, et c'est facile
  de passer de l'un à l'autre).
- La collation ne sert que pour les requêtes sql comme where truc = "aeiou" qui va sélectionner
  aussi du "ÀêïOù" avec une collation *_ci (avec du _cs je crois que "é"="e"), donc choisi _ci
  ou _cs ou _bin en fonction de ce qui t'arrange pour tes résultats de requêtes.



Réponse détaillée :

Certaines collations sont un peu plus rapides, mais c'est en général négligeable devant le reste
(la lecture des données et les jointures).

Attention quand même si tu utilises plusieurs langues, utf8_general_ci est plus "laxiste" que

utf8_general_ci :
  n = ñ
  ß = s

utf8_unicode_ci :
  n ≠ ñ
  ß = ss

Et attention aux collations spécifiques à une langue, par ex avec une collation spanish "ll"
est un caractère séparé entre l et n, donc "ll" > "lz" (ça parait très logique à un espagnol où
ll a une entrée séparée dans le dictionnaire).

Cf https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-sets.html


Avec une collation plus stricte (comme le _bin ou les _cs), les index prennent un peu plus de
place (plus d'entrées distinctes), mais c'est rarement un problème.

Pour le charset, celui que tu choisis doit contenir tous les caractères que tu veux pouvoir
stocker, mais à priori c'est le cas de tous les charset classiques pour les langues européennes
(utf8_*, latin1_*, …), et il peut influer sur la taille occupée par les données (donc espace
disque et dans une moindre mesure RAM occupée), mais ça changera pas grand choses sur la vitesse
d'exécution d'une requête.

Si tu veux vraiment économiser qq octets de disque et de RAM, le charset le plus économique
sera probablement latin1_general_ci, c'est pour ça que plein de gens continuent de l'utiliser
(aussi parce qu'ils n'ont jamais migré n'en éprouvant pas le besoin) sur des systèmes pourtant
en utf8.
Mais utiliser du mysql latin1 sur un OS utf8 oblige à préciser le charset lors de la connexion
à la base (pas mal de client vont le préciser d'office à la connexion), et depuis une appli
web ça peut être pénible (suivant que le charset de la page les post sont utf8 ou pas, et il
faudra décoder / encoder en entrée et sortie de la base suivant le charset de connexion, sinon
tu te retrouveras avec des trucs comme é sur tes pages web ou dans la base ou les deux).

C'est pour ça que c'est quand même plus simple d'avoir tout en utf8, qui est l'encodage par
défaut de pas mal de langages (et par ex le seul pour échanger des données en json).

Donc utf8mb4_general_c(i ou s) est probablement le meilleur choix pour la pérennité,
utf8_general_c(i|s) reste efficace avec une appli web utf8 et latin1_general_c(i|s) avec une
appli web iso8859 (charset des pages html en latin1), et _bin si tu veux des comparaisons
strictes (ou si les μs économisées sont importantes).

-- 
Daniel

Un jour Dieu me dit « cette chemise va t'aller » et "oh my Gad, Elmaleh"


Reply to: