Les codages de caractères autres que UTF-8 (et peut-être UTF-16 / UTF-32) devraient-ils être déconseillés?


31

Un de mes animaux de compagnie regarde tant de projets logiciels qui contiennent des montagnes de code pour la prise en charge des jeux de caractères. Ne vous méprenez pas, je suis pour la compatibilité et je suis heureux que les éditeurs de texte vous permettent d'ouvrir et d'enregistrer des fichiers dans plusieurs jeux de caractères. Ce qui m'agace, c'est comment la prolifération des encodages de caractères non universels est étiquetée «prise en charge Unicode appropriée» plutôt que «problème».

Par exemple, permettez-moi de choisir PostgreSQL et sa prise en charge des jeux de caractères . PostgreSQL gère deux types d'encodages:

  • Encodage client: utilisé dans la communication entre le client et le serveur.
  • Encodage serveur: utilisé pour stocker le texte en interne dans la base de données.

Je peux comprendre pourquoi la prise en charge de nombreux encodages client est une bonne chose. Il permet aux clients qui ne fonctionnent pas en UTF-8 de communiquer avec PostgreSQL sans avoir à effectuer eux-mêmes la conversion. Ce que je ne comprends pas, c'est: pourquoi PostgreSQL supporte-t-il plusieurs encodages de serveur ? Les fichiers de base de données sont (presque toujours) incompatibles d'une version PostgreSQL à la suivante, donc la compatibilité entre les versions n'est pas le problème ici.

UTF-8 est le seul jeu de caractères standard compatible ASCII qui peut coder tous les points de code Unicode (si je me trompe, faites le moi savoir). Je suis dans le camp que UTF-8 est le meilleur jeu de caractères, mais je suis prêt à accepter d'autres jeux de caractères universels tels que UTF-16 et UTF-32.

Je pense que tous les jeux de caractères non universels devraient être dépréciés. Y a-t-il une raison impérieuse de ne pas le faire?


4
@mario: La définition originale de UTF-8 permettait jusqu'à 6 octets. Il a ensuite été artificiellement restreint pour ne couvrir que les caractères que l'UTF-16 pouvait prendre en charge.
dan04

6
Au moins, PostgreSQL traite délibérément les encodages à plusieurs caractères. Ça craint d'avoir à composer avec un mélange aléatoire d'UTF-8 et de windows-1252 parce que quelqu'un s'en fichait.
dan04

5
@ dan04: Travailler avec des textes russes était pénible, car ils utilisaient plusieurs encodages qui étaient substantiellement différents et hachaient généralement les choses à travailler en utilisant différentes polices (ce qui mentait souvent sur l'encodage utilisé dans leurs métadonnées). Dans l'ensemble, un désordre horrible. Je soupçonne cependant qu'ils ont nettoyé - probablement en passant à UTF-8 - parce que le nombre de demandes d'assistance de cette direction a chuté.
Donal Fellows

3
La plage théorique Unicode est de 0 à 0x10ffff. Rien de plus. C'est ce que dit la norme Unicode. UTF-8 gère tout Unicode et le fera toujours. Il ne couvre pas la plage hypothétique d'un encodage qui n'est pas Unicode, mais il couvre tout Unicode.
gnasher729

Réponses:


16

Puisque vous avez mentionné PostgreSQL, je peux dire avec une certaine autorité que la principale raison qui tue pourquoi les encodages côté serveur non UTF8 sont pris en charge de manière si détaillée est que les Japonais en ont besoin. Apparemment, une conversion aller-retour identique entre Unicode et les divers encodages "hérités" japonais n'est pas toujours possible, et dans certains cas, les tables de conversion sont même différentes d'un fournisseur à l'autre. C'est vraiment déroutant, mais c'est apparemment le cas. (La prise en charge étendue des jeux de caractères est également l'une des raisons pour lesquelles PostgreSQL est si populaire au Japon.)

Comme nous parlons d'un système de base de données, l'une des tâches principales est de pouvoir stocker et récupérer des données de manière fiable, comme défini par l'utilisateur, de sorte que la conversion de jeux de caractères avec perte ne volera pas parfois. Si vous avez affaire à un navigateur Web, par exemple, où tout ce qui compte vraiment est de savoir si le résultat semble correct, alors vous pourriez probablement vous en sortir avec moins d'encodages, mais dans un système de base de données, vous avez des exigences supplémentaires.

Certaines des autres raisons mentionnées dans d'autres réponses s'appliquent également comme arguments à l'appui. Mais tant que les Japonais y opposent leur veto, la prise en charge de la configuration des personnages ne peut pas être réduite.


Donc, à cause de ces encodages, la conversion de texte en UTF-8 et vice-versa est en général une perte? Même si la reconversion est effectuée immédiatement (plutôt que dans 6 mois)?
Joey Adams

Joey Adams: Apparemment oui.
Peter Eisentraut

3
Google pour «unification Han» pour voir pourquoi
Petr Viktorin

7

Deux raisons évidentes: selon les données que vous stockez, la conversion vers un format différent peut prendre un peu de temps et d'espace supplémentaire. Si vous stockez 400 mégaoctets d'informations, doubler les besoins de stockage n'est pas un problème - mais si vous stockez 400 téraoctets, cela commence à signifier un peu plus. La conversion de 400 téraoctets de données de (disons) Shift-JIS en UTF-x pourrait également prendre un peu de temps.

Cela devient particulièrement difficile si vous avez (par exemple) des garanties de disponibilité qui disent que la base de données sera disponible pour tous mais, disons, 10 minutes sur une année donnée, et que vous avez une base de données qui est mise à jour plusieurs centaines de fois par seconde. Attention, il est toujours possible de gérer des conversions majeures dans une telle situation, mais ce n'est pas quelque chose à entreprendre à la légère. Dans certains cas, il pourrait facilement prendre des années de planification pour se préparer à une telle conversion.

Si vous débutiez avec une base de données qui (par exemple) ne supportait que l'ASCII, il pourrait y avoir de bonnes raisons de débattre de la pertinence d'ajouter la prise en charge de tous ces encodages - mais si vous les supportez déjà, il n'y a pas grand-chose à gagner à abandonner soutien pour eux.

Notez, en particulier, que vous gagneriez probablement presque rien dans la manière de simplifier le code, ou quelque chose comme ça. De toute façon, ils auraient besoin de toutes les routines de conversion pour gérer les conversions entre le client et le serveur. En tant que tel, la suppression du support signifierait la suppression d'un appel de fonction (mineur) dans les chemins "d'écriture sur le disque" et de "lecture à partir du disque", mais peu (le cas échéant). Si vous preniez en charge même deux encodages sur le disque, vous n'y gagneriez même pas - vous auriez toujours l'appel de fonction là-bas, donc tout ce que vous feriez vraiment serait de restreindre la plage d'encodages pris en charge par cette fonction.

Au moins, si je concevais cela, j'écrirais probablement le cœur de la base de données pour travailler dans UCS-4, puis j'aurais des routines de conversion entre le cœur et le disque, et entre le cœur et l'utilisateur. J'utiliserais le même ensemble de routines dans les deux cas, donc la voie la plus simple serait de permettre au stockage sur disque d'utiliser exactement le même ensemble d'encodages que les clients étaient autorisés à utiliser.


1
Shift-JIS n'est pas auto-synchronisé, ce qui rend la recherche fastidieuse. Vous souhaitez acquérir une simplification importante de ne pas le soutenir.
dan04

@ dan04: si vous avez déjà des routines de recherche / indexation éprouvées pour Shift-JIS, le passage à UTF-8 ou même UCS2 améliorerait probablement les performances de manière insignifiante. Pour une nouvelle base de données, vous pouvez choisir un encodage meilleur, plus pratique et régulier, comme UCS2 ou UTF-16.
9000

@ dan04: si vous pouviez vous en sortir sans le supporter du tout, vous en gagneriez un peu. Tant que vous soutenez qu'il vient de / va aux clients, vous allez être coincé avec la plupart de sa laideur ...
Jerry Coffin

5

Il y a quelques problèmes avec seulement le stockage UTF-8 sur le serveur:

  1. Quelle est la limite d'une VARCHAR(20)colonne? S'agit-il de 20 octets, ou 20 "caractères" (et en Unicode, qu'est-ce qu'un "caractère" lorsque vous prenez en compte la combinaison de caractères, de ligatures, etc.?). Pire, qu'en est-il de l' CHAR(20)endroit où il doit réellement réserver tout l'espace possible: je crois en MySQL, il réserve 4 fois le nombre d'octets pour une colonne encodée UTF-8 (donc 80 octets pour CHAR(20)) juste pour gérer le pire des cas.
  2. Vous devez effectuer des conversions d'encodage constantes entre l'encodage serveur et l'encodage client. Vous pourriez faire valoir que vous souhaitez également cesser de prendre en charge plusieurs encodages client, mais à moins que vous ne le fassiez, toutes les chaînes doivent être converties en permanence. Si vous pouvez faire correspondre l'encodage de votre serveur et l'encodage client, les conversions ne sont pas nécessaires.
  3. Comme d'autres l'ont souligné, l'UTF-8 est assez efficace pour stocker du texte anglais, mais il est très inefficace pour d'autres langues - les langues d'Asie de l'Est, en particulier. Vous pourriez autoriser l'utilisation de l'UTF-16 ou de l'UTF-8 comme combinaison, je suppose. Ou compresser du texte, mais cela rend l'indexation et la recherche inefficaces.

Cela dit, je suis d'accord avec vous: les encodages hérités sont pour la plupart inutiles et Unicode est généralement le meilleur encodage à utiliser pour toutes les nouvelles applications. Si j'écrivais un serveur de base de données à partir de zéro aujourd'hui, je prendrais uniquement en charge Unicode et ne prendrais en charge aucun encodage hérité.

La différence est que PostgreSQL et la plupart des autres serveurs de bases de données utilisés aujourd'hui existaient avant qu'Unicode ne soit une option viable. Donc, ils avaient déjà pris en charge les encodages hérités (ils n'étaient pas hérités à l'époque, bien sûr) et il n'y a tout simplement pas beaucoup d'intérêt à déchirer tout ce code pour des raisons largement idéologiques.


10
"mais c'est très inefficace pour d'autres langues - les langues d'Asie de l'Est en particulier" Même dans la pratique? Considérez cette page Wikipédia chinoise . Même s'il affiche énormément de caractères chinois, dans la source de la page, les caractères ASCII les submergent presque 7: 1.
Joey Adams

2
Si le N dans votre colonne CHAR (N) fait partie d'un format d'identificateur bien défini (par exemple, un VIN est défini pour être exactement 17 caractères), alors il n'a probablement pas besoin de combiner des caractères ou des ligatures. Sinon, alors N est juste une limite arbitraire, qui doit être interprétée généreusement pour éviter de tronquer les données.
dan04

5
@Joey Adams: c'est vrai du HTML et du XML où le balisage lui-même constitue une grande partie du texte (et c'est pourquoi je pense que l'UTF-8 est un bon choix pour le web), mais dans une base de données que vous ne stockez pas souvent HTML. À la fin de la journée, ce n'est qu'un facteur de deux (ou moins) de différence, ce qui n'est pas vraiment.
Dean Harding le

5
Le point n ° 2 de cette réponse n'est pas pertinent: il s'applique, que Unicode soit utilisé ou non. Le point n ° 3 exagère absolument l'inefficacité et sa portée. Dans le même temps, cette réponse sous-estime largement les problèmes causés par les encodages hérités. Il est facile de supposer que le problème n'est pas si grave si tout ce que vous utilisez dans votre vie est l'anglais.
Timwi

2
@Dean: Je ne savais pas qu'il n'était pas permis de commenter une réponse sans poster la mienne.
Timwi

3

Les codages non universels (et spécifiquement à un octet) ont leur place: sur les systèmes qui:

  • Vous n'avez pas assez de mémoire pour stocker la base de données de caractères Unicode.
  • Avoir une police à un octet codée en dur dans la ROM.
  • N'ont pas accès à Internet pour fournir une source de fichiers codés différemment.

C'est vrai aujourd'hui pour certains types d'appareils intégrés. Mais sur le bureau et dans la salle des serveurs, les encodages non Unicode devraient être obsolètes depuis longtemps .


3
J'avais des ordinateurs personnels comme ça. Je me suis débarrassé de la plupart d'entre eux au début des années 80.
David Thornley

2

UTF-8 est le meilleur pour vous anglophone égocentrique 1 . Si vous étiez japonais, environ 99% de vos personnages prendraient 3-4 octets au lieu de deux en UTF-16.

Les dialectes non latins souffrent vraiment de l'UTF-8 au niveau de la taille. N'oubliez pas que d'ici quelques années, la plupart de vos clients pourraient être chinois, et l'écriture chinoise a des millions de caractères. Vous ne pouvez pas supporter cela efficacement avec UTF-8.

Sinon, je déteste quand j'ai des documents texte qui ne sont pas en UTF - quelque chose . Je vais souvent m'éloigner si j'ai besoin d'avoir un bon encodage. Dans mon livre, les encodages non Unicode sont morts.

1. Ne prenez pas personnellement la partie égocentrique. Je voulais faire une illustration colorée et je ne le pense pas vraiment.


3
@Matthew - 4x est clairement 4 fois plus grand que x (pour x positif). Je ne vois pas en quoi la notation asymptotique est pertinente ici. Je n'ai jamais vu un disque dur annoncé avec un taux de croissance asymptotique. Normalement, la taille reste la même pendant toute la durée de vie du lecteur.
Steve314

3
Des millions de personnages ne rentreront de toute façon pas dans Unicode. Selon l'article de Wikipedia, il y a actuellement environ soixante mille caractères Han. Étant donné qu'Unicode n'est pas seulement chinois, cela signifie qu'un bon nombre de caractères chinois prendront quatre octets en UTF-16, ce qui est aussi long que UTF-8 est de nos jours. Il serait intéressant de voir des statistiques sur les longueurs des textes chinois en UTF-8 et UTF-16.
David Thornley

6
@David:> 99% de toute l'écriture japonaise et chinoise utilise des caractères qui ne nécessitent que 2 octets en UTF-16 et 3 en UTF-8. Les personnages qui en demandent plus sont très rares et / ou historiques.
Timwi

8
Gardez à l'esprit que le japonais et le chinois utilisent généralement moins de caractères par mot. Je travaille avec une application qui contient de gros fichiers de langue en anglais, japonais et chinois, tous encodés en utf-8. Le fichier chinois est en fait le plus petit, tandis que le fichier japonais est environ 15% plus gros que l'original anglais.
Gort the Robot

3
Absurdité. Tout ce qui prend deux octets en UTF-16 ne prend pas plus de 3 octets en UTF-8. Tout ce qui est de quatre octets en UTF-8 est de 4 octets en UTF-16. Il n'y a pas de «millions» de caractères chinois et, évidemment, ils ne tiendraient pas en 16 bits.
gnasher729

1

Unicode est fondamentalement cassé et il est peu probable qu'il ait jamais été corrigé. Il doit être remplacé par quelque chose de mieux, quelque chose de vraiment universel. Si quelque chose doit être déconseillé, c'est Unicode.

Exemples de problèmes avec Unicide:

  • UTF8 est un hack raisonnable, mais la plupart des logiciels basés sur UTF16 sont cassés. La plupart des applications Windows qui prennent en charge Unicode utilisent UTF16, y compris le système d'exploitation lui-même. Le problème le plus courant ne prend pas en charge plus que le plan de base, c'est-à-dire les caractères multi-mots.

  • L'unification des Han est un désastre absolu. Il est impossible de mélanger du texte japonais / chinois / coréen dans un seul document sans métadonnées supplémentaires, et difficile de détecter la police à utiliser.

  • Les personnages multinationaux sont un autre désastre. Des schémas de codage plus judicieux mappent un caractère à un code, ce qui rend le traitement des chaînes relativement sain. Unicode ne fonctionne pas. Unicode n'est même pas cohérent - les caractères Han sont principalement des combinaisons, mais ne sont pas codés en tant que tels, contrairement aux caractères combinatoires européens.

  • Les noms de certaines personnes ne peuvent pas être écrits correctement en Unicode, ou sont très susceptibles d'être rendus incorrectement en raison des problèmes mentionnés ci-dessus. Cela peut avoir de graves conséquences, par exemple lorsque vous essayez d'embarquer dans un avion avec un passeport qui ne correspond pas à ce qui est (incorrectement) imprimé sur le billet.

En raison de ces problèmes et bien plus, de nombreux logiciels non anglais ne peuvent pas utiliser Unicode et s'appuient sur des encodages de caractères locaux. Cela est particulièrement courant avec les logiciels japonais et chinois.

Idéalement, Unicode devrait être obsolète. Le codage de caractères TRON est un assez bon remplacement pour Unicode et largement compatible avec les logiciels existants qui ne seront pas mis à jour.


Votre affirmation selon laquelle il est impossible de mélanger les différentes variantes de caractères (japonais / coréen / chinois) semble obsolète depuis 15 ans, la norme Unicode 3.2 en 2002. Unicode prend en charge les sélecteurs de variation, points de code qui après un point de code han spécifient explicitement quelle forme doit être affiché. De plus, les caractères combinatoires sont spécifiés à la fois comme "combinaison de signes diacritiques" avec des caractères de base (a °) et des glyphes spéciaux (å), le processus de conversion inversé est la "normalisation". Donc, non, Unicode n'est pas fondamentalement cassé.
Thorsten S.

Vous illustrez bon nombre des défauts. Certaines langues utilisent des caractères combinatoires, d'autres non, et Unicode ne peut pas décider lequel il préfère. Comme je l'ai souligné, la plupart des logiciels qui prétendent prendre en charge Unicode ne comprennent pas ces problèmes de toute façon et les afficheront mal même avec les sélecteurs. Les programmeurs ne devraient pas être des experts en langage, ce qui est l'autre défaut fondamental d'Unicode.
utilisateur

0

Peut-être pour écrire, mais pas pour lire.

Il y a beaucoup de contenu existant qui utilise ces encodages, et certains encodages comme base64 ne vont nulle part parce que certains protocoles de texte les obligent à incorporer des données binaires.

Un vrai problème est la détection automatique des encodages qui conduit à des failles de sécurité. Cela ne me dérangerait pas de voir certains encodages obscurs comme UTF-7 disparaître.

La détection automatique a également tendance à mal gérer le contenu produit par la concaténation naïve de chaînes d'octets.


7
Base64 n'est pas un encodage de caractères.
dan04

0

Je peux convenir que le codage de caractères par défaut pour les bases de données et les nouvelles applications devrait être une sorte de variante UTF. Personnellement, j'opterais pour UTF-16 car il semble que ce soit un compromis raisonnable en termes d'espace et de complexité (plus que UTF-8). Cela dit, certains encodages de caractères ont toujours un sens dans certains cas.

  • Si vous stockez / transférez du texte base64, vous n'avez besoin que d'ASCII et vous pouvez même vous en sortir avec des protocoles codés en 7 bits comme le courrier électronique. La surcharge supplémentaire de l'UTF-8 n'est pas nécessaire.
  • Plusieurs fichiers et données existantes sont construits sur ces anciens encodages de caractères, pouvoir les lire est important.

Notez qu'il existe 4 algorithmes de normalisation UTF standard. Si vous êtes préoccupé par les caractères multi-points de code, vous pouvez utiliser l'un des deux algorithmes de normalisation qui les réduisent en caractères mono-points de code équivalents. La différence entre eux a à voir avec l'équivalence logique contre l'équivalence physique des personnages.


1
Les votants peuvent- ils dire pourquoi ils ont voté contre?
Berin Loritsch

3
Je n'ai pas downvote, mais tout l'intérêt de base64 est de transférer des données binaires sur un canal de texte. Si vous pouviez choisir l'encodage à utiliser sur cette chaîne, vous n'utiliseriez pas du tout d'encodage de texte. Même si votre canal est vraiment en ASCII, la base 64 n'utilise que 6 bits sur 7 - un surdébit déjà considérable.
Steve314

J'espère que quelqu'un n'a pas seulement lu les puces. Ce sont les exceptions à l'utilisation de l'UTF. Et vous vous trompez sur la base 64 en utilisant uniquement 6 octets sur 8. Le premier ensemble de "caractères" ASCII sont des caractères de contrôle non imprimables, ce qui oblige certains des caractères de base64 à utiliser 7 des 8 octets. Il évite délibérément le bit élevé car tous ces caractères ne sont pas garantis d'exister dans chaque page de code, tandis que les caractères de 0 à 127 le sont.
Berin Loritsch

2
@Berin - (1) non, mais ce "je suis d'accord" n'est pas beaucoup sans les puces, et (2) la base 64 a 64 "chiffres". 64 chiffres valent 6 bits, car 2 ^ 6 == 64. La façon dont vous représentez cela dans un espace de code de 7 bits (ou 8 bits, voire 8 octets si vous le devez) est distincte de la quantité de données réellement présentes. Éviter les caractères non imprimables, etc. est la raison de la surcharge - cela ne signifie pas que la surcharge n'existe pas. Choisissez un canal conçu pour les données binaires et cette surcharge n'est pas là.
Steve314

3
Gardez à l'esprit que base64 a été inventé pour gérer l'envoi de données binaires sur un canal texte uniquement. Il est connu pour être inefficace (extension 3: 4), mais traite des limitations techniques de certaines options de transport. L'héritage serait les e-mails et les forums UseNet, mais une application plus moderne incorporerait des données binaires dans XML. Parfois, le canal approprié n'existe pas et vous devez surmonter les limitations des canaux existants.
Berin Loritsch
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.