¿Deben las codificaciones de caracteres además de UTF-8 (y tal vez UTF-16 / UTF-32) en desuso?

31

Una mascota mía está mirando tantos proyectos de software que tienen montañas de código para el soporte de juegos de caracteres. No me malinterpreten, estoy a favor de la compatibilidad, y estoy feliz de que los editores de texto le permitan abrir y guardar archivos en múltiples conjuntos de caracteres. Lo que me molesta es cómo la proliferación de codificaciones de caracteres no universales se denomina "soporte Unicode adecuado" en lugar de "un problema".

Por ejemplo, permítanme elegir PostgreSQL y su compatibilidad con juegos de caracteres . PostgreSQL trata con dos tipos de codificaciones:

  • Codificación del cliente: se utiliza en la comunicación entre el cliente y el servidor.
  • Codificación del servidor: se utiliza para almacenar texto internamente en la base de datos.

Puedo entender por qué apoyar una gran cantidad de codificaciones de clientes es algo bueno. Permite a los clientes que no operan en UTF-8 comunicarse con PostgreSQL sin necesidad de realizar la conversión. Lo que no entiendo es: ¿por qué PostgreSQL admite múltiples codificaciones de servidor ? Los archivos de base de datos son (casi siempre) incompatibles de una versión de PostgreSQL a la siguiente, por lo que la compatibilidad entre versiones no es el problema aquí.

UTF-8 es el único juego de caracteres estándar compatible con ASCII que puede codificar todos los puntos de código Unicode (si estoy equivocado, hágamelo saber). Estoy en el campo de que UTF-8 es el mejor conjunto de caracteres, pero estoy dispuesto a soportar otros conjuntos de caracteres universales como UTF-16 y UTF-32.

Creo que todos los juegos de caracteres no universales deberían ser obsoletos. ¿Hay alguna razón convincente para que no lo hagan?

Joey Adams
fuente
44
@mario: La definición original de UTF-8 permitía hasta 6 bytes. Más tarde se restringió artificialmente para cubrir solo los caracteres que UTF-16 podía soportar.
dan04
66
Al menos PostgreSQL trata deliberadamente con codificaciones de caracteres múltiples. Es una mierda tener que lidiar con una mezcla aleatoria de UTF-8 y windows-1252 porque a alguien simplemente no le importaba.
dan04
55
@ dan04: Trabajar con textos en ruso solía ser una molestia, ya que usaban codificaciones múltiples que eran sustancialmente diferentes y generalmente hackeaban las cosas para que funcionaran usando diferentes fuentes (que a menudo mentirían sobre la codificación en uso en sus metadatos). En general, un desastre horrible. Sin embargo, sospecho que han limpiado, probablemente moviéndose a UTF-8, porque la cantidad de solicitudes de soporte desde esa dirección se ha reducido de inmediato.
Donal Fellows
3
El rango teórico de Unicode es de 0 a 0x10ffff. Nada mas. Eso es lo que dice el estándar Unicode. UTF-8 maneja todo Unicode y siempre lo hará. No cubre el rango hipotético de una codificación que no es Unicode, pero cubre todo Unicode.
gnasher729

Respuestas:

16

Como mencionó PostgreSQL, puedo decir con cierta autoridad que la razón principal por la que las codificaciones del lado del servidor que no son UTF8 son compatibles con tanto detalle es que los japoneses lo necesitan. Aparentemente, la conversión de ida y vuelta idéntica entre Unicode y las diversas codificaciones "heredadas" japonesas no siempre es posible, y en algunos casos las tablas de conversión son incluso diferentes entre los proveedores. Es realmente desconcertante, pero aparentemente es así. (El amplio soporte de juegos de caracteres también es una de las razones por las que PostgreSQL es tan popular en Japón).

Dado que estamos hablando de un sistema de base de datos, uno de los trabajos principales es poder almacenar y recuperar datos de manera confiable, según lo definido por el usuario, para que la conversión de juegos de caracteres con pérdidas a veces no funcione. Si estaba tratando con un navegador web, digamos, donde todo lo que realmente importa es si el resultado se ve bien, entonces probablemente podría salirse con la suya admitiendo menos codificaciones, pero en un sistema de base de datos tiene requisitos adicionales.

Algunas de las otras razones mencionadas en otras respuestas también se aplican como argumentos de apoyo. Pero mientras los japoneses lo veten, el soporte de configuración de personajes no se puede reducir.

Peter Eisentraut
fuente
Entonces, debido a estas codificaciones, la conversión de texto a UTF-8 y viceversa es con pérdida en general. ¿Incluso si la conversión se realiza de inmediato (en lugar de 6 meses a partir de ahora)?
Joey Adams
Joey Adams: Aparentemente sí.
Peter Eisentraut
3
Google para "Han unificación" para ver por qué
Petr Viktorin
7

Dos razones obvias: dependiendo de los datos que esté almacenando, la conversión a un formato diferente podría llevar bastante tiempo y espacio extra. Si está almacenando 400 megabytes de información, duplicar los requisitos de almacenamiento no es gran cosa, pero si está almacenando 400 terabytes, comienza a significar un poco más. La conversión de 400 terabytes de datos de (digamos) Shift-JIS a UTF-x también podría llevar un poco de tiempo.

Esto se vuelve especialmente difícil si tiene (por ejemplo) garantías de tiempo de actividad que dicen que la base de datos estará disponible para todos, pero, digamos, 10 minutos de un año determinado, y tiene una base de datos que se actualiza varios cientos de veces por segundo. Eso sí, sigue siendo posible para gestionar las transformaciones importantes en tal situación una, pero es no algo para tomarse a la ligera. En algunos casos, podría llevar años de planificación prepararse para tal conversión.

Si comenzara con una base de datos que (por ejemplo) solo era compatible con ASCII, podría haber una buena razón para debatir si tenía sentido agregar soporte para todas esas codificaciones, pero si ya las admite, hay poco que ganar al dejarlas caer. apoyo para ellos.

Tenga en cuenta, en particular, que probablemente no ganaría casi nada en la forma de simplificar el código, o algo así. Todavía necesitarían todas las rutinas de conversión para lidiar con las conversiones entre el cliente y el servidor de todos modos. Como tal, abandonar el soporte significaría eliminar una llamada de función (menor) en las rutas "escribir en el disco" y "leer desde el disco", pero poco (si es que hay algo más). Si admitiera incluso dos codificaciones en el disco, ni siquiera ganaría eso: aún tendría la llamada a la función allí, por lo que todo lo que realmente haría sería restringir el rango de codificaciones admitidas por esa función.

Al menos si estuviera diseñando esto, probablemente escribiría el núcleo de la base de datos para trabajar en UCS-4, y luego tendría rutinas de conversión entre el núcleo y el disco, y entre el núcleo y el usuario. Usaría el mismo conjunto de rutinas en ambos casos, por lo que la ruta más simple sería permitir que el almacenamiento en disco use exactamente el mismo conjunto de codificaciones que los clientes podían usar.

Jerry Coffin
fuente
1
Shift-JIS no se sincroniza automáticamente, lo que dificulta la búsqueda. Usted podría ganar simplificación significativa por que no lo soporte.
dan04
@ dan04: si ya tiene rutinas de búsqueda / indexación probadas para Shift-JIS, cambiar a UTF-8 o incluso UCS2 probablemente mejoraría el rendimiento de manera insignificante. Para una nueva base de datos, puede elegir una codificación mejor, más conveniente y regular, como UCS2 o UTF-16.
9000
@ dan04: si pudieras salirte con la tuya sin apoyarlo, ganarías bastante. Mientras lo respalde viniendo de / yendo a clientes, se quedará atrapado con la mayor parte de su fealdad ...
Jerry Coffin
5

Hay un par de problemas con solo almacenar UTF-8 en el servidor:

  1. ¿Cuál es el límite de una VARCHAR(20)columna? ¿Son 20 bytes o 20 "caracteres" (y en Unicode, ¿qué es un "carácter" cuando tiene en cuenta la combinación de caracteres, ligaduras, etc.?) Peor aún, ¿qué pasa CHAR(20)si realmente tiene que reservar todo el espacio posible? Creo en MySQL, reserva 4 veces la cantidad de bytes para una columna codificada UTF-8 (80 bytes para CHAR(20)) solo para manejar el peor de los casos.
  2. Debe realizar conversiones de codificación constantes entre la codificación del servidor y la codificación de su cliente. Podría argumentar que también quiere dejar de admitir múltiples codificaciones de clientes, pero a menos que lo haga, entonces todas las cadenas deben convertirse todo el tiempo. Si puede hacer coincidir la codificación del servidor y la codificación del cliente, entonces no se requieren las conversiones.
  3. Como otros han señalado, UTF-8 es bastante eficiente para almacenar texto en inglés, pero es muy ineficiente para otros idiomas, en particular los idiomas de Asia oriental. Supongo que podría permitir el uso de UTF-16 o UTF-8 como trajes. O comprimir texto, pero eso hace que la indexación y la búsqueda sean ineficientes.

Habiendo dicho todo eso, estoy de acuerdo con usted: las codificaciones heredadas en su mayoría no tienen sentido y Unicode es generalmente la mejor codificación para usar en todas las aplicaciones nuevas. Si hoy escribiera un servidor de base de datos desde cero, solo admitiría Unicode y no admitiría ninguna codificación heredada.

La diferencia es que PostgreSQL y la mayoría de los otros servidores de bases de datos en uso hoy existían antes de que Unicode fuera una opción viable. Por lo tanto, ya tenían soporte para codificaciones heredadas (no eran heredadas en ese entonces, por supuesto) y simplemente no tiene mucho sentido extraer todo ese código por razones en gran parte ideológicas.

Dean Harding
fuente
10
"pero es muy ineficiente para otros idiomas, especialmente los idiomas de Asia oriental" ¿ Incluso en la práctica? Considere esta página de Wikipedia en chino . A pesar de que muestra una gran cantidad de caracteres chinos, en la fuente de la página, los caracteres ASCII los abruman casi 7: 1.
Joey Adams
2
Si la N en su columna CHAR (N) es parte de un formato de identificador bien definido (por ejemplo, un VIN se define con exactamente 17 caracteres), entonces probablemente no necesite combinar caracteres o ligaduras. Si no, entonces N es solo un límite arbitrario, que debe interpretarse generosamente para evitar el truncamiento de datos.
dan04
55
@Joey Adams: eso es cierto para HTML y XML, donde el marcado en sí mismo constituye una gran proporción del texto (y es por eso que creo que UTF-8 es una buena opción para la web), pero en una base de datos que a menudo no se almacena HTML Al final del día, es solo un factor de dos (o menos) diferencia, que en realidad no es tanto.
Dean Harding
55
La viñeta n. ° 2 en esta respuesta es irrelevante: se aplica independientemente de si se utiliza Unicode o no. La viñeta n. ° 3 exagera absolutamente la ineficiencia y su alcance. Al mismo tiempo, esta respuesta subestima enormemente los problemas causados ​​por las codificaciones heredadas. Es fácil asumir que el problema no es tan importante si todo lo que usa en su vida es el inglés.
Timwi
2
@Dean: No sabía que no estaba permitido comentar una respuesta sin publicar una propia.
Timwi
3

Las codificaciones no universales (y específicamente de un solo byte) tienen su lugar: en sistemas que:

  • No tiene suficiente memoria para almacenar la base de datos de caracteres Unicode.
  • Tener una fuente de un solo byte codificada en ROM.
  • No tiene acceso a Internet para proporcionar una fuente de archivos codificados de manera diferente.

Eso es cierto hoy para algunos tipos de dispositivos integrados. Pero en el escritorio, y en la sala de servidores, codificaciones no Unicode deben ser a largo obsoleta por ahora.

dan04
fuente
3
Solía ​​tener computadoras hogareñas como esa. Me deshice de la mayoría de ellos a principios de los 80.
David Thornley
2

UTF-8 es el mejor para usted egocéntrico 1 hablante de inglés. Si fuera japonés, aproximadamente el 99% de sus caracteres tomarían 3-4 bytes en lugar de dos en UTF-16.

Los dialectos no latinos realmente sufren de UTF-8 en el nivel de tamaño. No olvide que dentro de unos años, la mayoría de sus clientes podrían ser chinos, y la escritura china tiene millones de caracteres. No puede sostener eso de manera eficiente con UTF-8.

De lo contrario, odio cuando tengo documentos de texto que no están en UTF, algo . A menudo saldré de mi camino si necesito tener una codificación adecuada. En mi libro, las codificaciones no Unicode están muertas.

1. No tome la parte egocéntrica personalmente. Quería hacer una ilustración colorida y no lo digo en serio.

zneak
fuente
3
@Matthew - 4x es claramente 4 veces más grande que x (para x positivo). No veo cómo la notación asintótica es relevante aquí. Nunca he visto un disco duro anunciado con una tasa de crecimiento asintótica. Normalmente, el tamaño se mantiene igual durante toda la vida útil del disco.
Steve314
3
Millones de personajes no caben en Unicode de todos modos. Según el artículo de Wikipedia, actualmente hay unos sesenta mil caracteres Han. Dado que Unicode no es solo chino, eso significa que un buen número de caracteres chinos ocupará cuatro bytes en UTF-16, que es el tiempo que UTF-8 tiene hoy en día. Sería interesante ver estadísticas sobre la longitud de los textos chinos en UTF-8 y UTF-16.
David Thornley
66
@David:> 99% de toda la escritura japonesa y china usa caracteres que requieren solo 2 bytes en UTF-16 y 3 en UTF-8. Los personajes que requieren más son muy raros y / o históricos.
Timwi
8
Tenga en cuenta que los japoneses y los chinos generalmente usan menos caracteres por palabra. Trabajo con una aplicación que tiene grandes archivos de idiomas en inglés, japonés y chino, todos codificados en utf-8. El archivo chino es en realidad el más pequeño, mientras que el archivo japonés es aproximadamente un 15% más grande que el original en inglés.
Gort the Robot
3
Disparates. Cualquier cosa que tome dos bytes en UTF-16 no toma más de 3 bytes en UTF-8. Cualquier cosa que sea de cuatro bytes en UTF-8 es de 4 bytes en UTF-16. No hay "millones" de caracteres chinos, y obviamente no encajarían en 16 bits.
gnasher729
1

Unicode está fundamentalmente roto y es poco probable que se repare alguna vez. Necesita ser reemplazado por algo mejor, algo verdaderamente universal. Si algo necesita degradarse, es Unicode.

Ejemplos de problemas con Unicide:

  • UTF8 es un truco razonable, pero la mayoría del software basado en UTF16 está dañado. La mayoría de las aplicaciones de Windows que admiten Unicode usan UTF16, incluido el sistema operativo. El problema más común no es admitir más que el plano básico, es decir, caracteres de varias palabras.

  • La unificación de Han es un desastre no mitigado. Es imposible mezclar texto japonés / chino / coreano en un solo documento sin metadatos adicionales, y es difícil detectar qué fuente se debe usar.

  • Los personajes combinacionales son otro desastre. Los esquemas de codificación más razonables asignan un carácter a un código, lo que hace que las cadenas de procesamiento sean relativamente sensatas. Unicode no lo hace. Unicode ni siquiera es consistente: los caracteres Han son en su mayoría combinaciones, pero no están codificados como tales, como lo están los caracteres combinacionales europeos.

  • Los nombres de algunas personas no se pueden escribir correctamente en Unicode, o son muy propensos a mostrarse incorrectamente debido a los problemas mencionados anteriormente. Esto puede tener graves consecuencias, por ejemplo, cuando se trata de abordar un avión con un pasaporte que no coincide con lo que está impreso (incorrectamente) en el boleto.

Debido a estos problemas y más, una gran cantidad de software que no está en inglés no puede usar Unicode y se basa en codificaciones de caracteres locales. Esto es particularmente común con el software japonés y chino.

Idealmente, Unicode debería estar en desuso. La codificación de caracteres TRON es un reemplazo bastante bueno para Unicode, y en gran medida compatible con el software existente que no se actualizará.

usuario
fuente
Su afirmación de que es imposible mezclar las diferentes variantes de caracteres (japonés / coreano / chino) parece estar desactualizada desde hace 15 años, el estándar Unicode 3.2 en 2002. Unicode admite selectores de variación, puntos de código que después de un punto de código han especifican explícitamente qué forma debe mostrarse Además, los caracteres combinatorios se especifican como "combinación de signos diacríticos" con caracteres base (a °) y glifos especiales (å), el proceso de convertirlos viceversa es "normalización". Entonces, no, Unicode no está fundamentalmente roto.
Thorsten S.
Ilustras muchos de los defectos. Algunos idiomas usan caracteres combinacionales, otros no, y Unicode no puede decidir cuál prefiere. Como señalé, la mayoría del software que afirma admitir Unicode no entiende esos problemas de todos modos y lo mostrará mal incluso con los selectores. No se debe esperar que los programadores sean expertos en idiomas, que es el otro defecto fundamental en Unicode.
usuario
0

Tal vez para escribir, pero no para leer.

Hay una gran cantidad de contenido existente que usa esas codificaciones, y algunas codificaciones como base64 no van a ninguna parte porque algunos protocolos de texto exigen esas formas de incrustar datos binarios.

Un problema real es la autodetección de codificaciones que conduce a agujeros de seguridad. No me importaría ver desaparecer algunas codificaciones oscuras como UTF-7 .

La detección automática también tiende a tratar mal el contenido producido al concatenar ingenuamente cadenas de bytes.

Mike Samuel
fuente
77
Base64 no es una codificación de caracteres.
dan04
0

Estoy de acuerdo en que la codificación de caracteres predeterminada para bases de datos y nuevas aplicaciones debería ser algún tipo de variante UTF. Yo personalmente optaría por UTF-16 ya que parece ser una compensación razonable en espacio y complejidad (más que UTF-8). Dicho esto, algunas codificaciones de caracteres todavía tienen sentido en ciertos casos.

  • Si está almacenando / transfiriendo texto base64, solo necesita ASCII e incluso puede salirse con la suya con protocolos codificados de 7 bits como el correo electrónico. La sobrecarga adicional de UTF-8 es innecesaria.
  • Varios archivos y datos existentes se basan en estas codificaciones de caracteres anteriores, por lo que es importante poder leerlos.

Tenga en cuenta que hay 4 algoritmos de normalización UTF estándar. Si le preocupan los caracteres de múltiples puntos de código, puede usar uno de los dos algoritmos de normalización que los colapsan en el carácter de punto de código único equivalente. La diferencia entre ellos tiene que ver con la equivalencia lógica versus la equivalencia física de los caracteres.

Berin Loritsch
fuente
1
¿Pueden los votantes negativos decir por qué votaron negativamente?
Berin Loritsch
3
No voté en contra, pero el objetivo de base64 es transferir datos binarios a un canal de texto. Si pudieras elegir qué codificación usar en ese canal, no usarías una codificación de texto en absoluto. Incluso si su canal realmente es ASCII simple, la base 64 solo usa 6 de 7 bits, una sobrecarga significativa ya.
Steve314
Espero que alguien no acaba de leer las viñetas. Esas fueron las excepciones al uso de UTF. Y usted es incorrecto acerca de la base 64 solo que usa 6 de 8 bytes. El primer conjunto de "caracteres" ASCII son caracteres de control no imprimibles, lo que obliga a algunos de los caracteres en base64 a utilizar 7 de los 8 bytes. Evita deliberadamente el bit alto porque no se garantiza que todos esos caracteres existan en cada página de códigos, mientras que los caracteres del 0-127 sí lo están.
Berin Loritsch 01 de
2
@Berin: (1) no, pero eso de "Estoy de acuerdo" no es mucho sin las viñetas, y (2) la base 64 tiene 64 "dígitos". 64 dígitos vale 6 bits, porque 2 ^ 6 == 64. La forma en que representa eso en un espacio de código de 7 bits (u 8 bits, o incluso 8 bytes si es necesario) es independiente de la cantidad de datos que hay realmente allí. La razón de la sobrecarga es evitar los caracteres que no se imprimen, etc. , no significa que la sobrecarga no exista. Elija un canal diseñado para datos binarios y esa sobrecarga no esté allí.
Steve314
3
Tenga en cuenta que base64 se inventó para tratar el envío de datos binarios a través de un canal de solo texto. Se sabe que es ineficiente (expansión 3: 4), pero trata con limitaciones técnicas en ciertas opciones de transporte. Legacy sería el correo electrónico y los foros de UseNet, pero una aplicación más moderna sería la incorporación de datos binarios en XML. A veces no existe el canal adecuado , y usted tiene que superar las limitaciones de los existentes.
Berin Loritsch 01 de