Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[hs] MySQL : utf8_general_ci ou utf8_unicode_ci ou utf8mb4_unicode_ci

2,037 views
Skip to first unread message

Dominique Asselineau

unread,
Jan 29, 2017, 4:00:03 PM1/29/17
to
Bonjour,

Je souhaite passer mes bases de donnéeds en UTF-8 et je remarque
plusieurs régblages possibles. D'après ce que je lis, il semble que le
réglage utf8mb4_unicode_ci soit le plus puissant et complet mais pas
sûr que ce soit le mieux adapté dans un environnement Debian.

Ce serveur ne tourne qu'en localhost, pas d'accès de client extérieur
donc. Il est seulement dépendant de l'environnement et locales de
Debian. Toutefois des données peuvent entrer via des formuliares web.

quelqu'un aurait-il un avis sur un réglage approprié des character set
et collation ?

A+

dom

--

Safranil

unread,
Jan 29, 2017, 6:20:02 PM1/29/17
to
Bonjour,

En fait l'UTF-8 de MySQL ne respecte pas la norme Unicode et ne supporte
que les caractères codés sur 3 octets (plan de base de l'Unicode), d'où
l'ajout de l'utf8-mb4 (multibytes 4) pour supporter complétement la
norme. À priori, cela ne vous posera pas de problème de choisir la
version non mb4 mais je conseil tout de même d'utiliser l'utf8-mb4 par
soucis de respect des normes.

Le fait que vous soyez sur Debian ou non ne changera en rien la gestion
des caractères dans MySQL, le système ne fourni que le stockage des
bases de données et non l'interprétation des caractères contenu à
l'intérieur, rôle joué par le moteur de bases de données.

Pour la collation, j'utilise utf8mb4_bin car la comparaison des chaines
de caractères sont effectué bit à bit (donc sensible à la casse) alors
que les utf8mb4_xxx_ci compare les chaînes de caractères indépendamment
de la casse (et accents il me semble) en appliquant des règles
spécifiques à la langue. Si vous êtes dans le second cas, je vous
conseil l'utf8mb4_general_ci qui gère parfaitement la langue française.

En espérant avoir répondu à vos questions.

Bonne soirée.
signature.asc

Dominique Asselineau

unread,
Jan 30, 2017, 9:00:03 AM1/30/17
to
Bonjour et merci de ces précisions.

Le contexte serait un peu plus large que le français mais ça resterait
parmi les langues européennes. Dans ce cas utf8mb4_general_ci
serait-il toujours performant ?

Merci.

Dominique


Safranil wrote on Mon, Jan 30, 2017 at 12:03:41AM +0100
--

Daniel Caillibaud

unread,
Jan 31, 2017, 9:10:02 AM1/31/17
to
Le 30/01/17 à 14:55, Dominique Asselineau <asse...@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"

Dominique Dumont

unread,
Feb 11, 2017, 9:00:08 AM2/11/17
to
On lundi 30 janvier 2017 00:03:41 CET Safranil wrote:
> Si vous êtes dans le second cas, je vous
> conseil l'utf8mb4_general_ci qui gère parfaitement la langue française.

D'après Tom Christieansen [1], utf8mb4_general_ci est cassé. Il faut utiliser
utf8mb4_unicode_ci.

utf8mb4_general_ci est peut-être suffisant pour le Français, mais dans le doute,
le plus simple est d'utiliser utf8mb4_unicode_ci

HTH

[1] http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci#766996

Eric Degenetais

unread,
Feb 12, 2017, 5:00:02 AM2/12/17
to
>utf8mb4_general_ci est peut-être >suffisant pour le Français, mais dans le >doute,
>le plus simple est d'utiliser >utf8mb4_unicode_ci
Bonjour, en fait le français aussi utilise un caractère composé : œ comme dans œil ou œuf. Donc (je n'ai pas testé, mais il est probable que les approximations de général_ci soient visibles en français. 

Dominique Asselineau

unread,
Feb 13, 2017, 6:30:03 AM2/13/17
to
Eric Degenetais wrote on Sun, Feb 12, 2017 at 09:55:11AM +0000
Justement, avec utf8mb4_general_ci, l'ordre alphabétique n'est pas
correct. Le œ est rejeté à la fin de l'alphabet. Le ß semble
toutefois être bien placé.

mb4_unicode_ci semble être plus précis sur l'ordre alphabétique. Les
ligatures œ et ß sont normalement assimilés à oe et ss et placés en
conséquence.



--
0 new messages