Le codifiche dei caratteri oltre a UTF-8 (e forse UTF-16 / UTF-32) dovrebbero essere deprecate?


31

Un mio peeve pet sta guardando così tanti progetti software che hanno montagne di codice per il supporto del set di caratteri. Non fraintendetemi, sono tutto per compatibilità e sono felice che gli editor di testo ti consentano di aprire e salvare file in più set di caratteri. Ciò che mi dà fastidio è come la proliferazione di codifiche di caratteri non universali sia etichettata come "supporto Unicode adeguato" piuttosto che "un problema".

Ad esempio, lasciami scegliere PostgreSQL e il suo supporto per i set di caratteri . PostgreSQL si occupa di due tipi di codifica:

  • Codifica client: utilizzata nella comunicazione tra client e server.
  • Codifica server: utilizzata per archiviare il testo internamente nel database.

Capisco perché supportare molte codifiche client sia una buona cosa. Consente ai client che non operano in UTF-8 di comunicare con PostgreSQL senza che debbano eseguire la conversione. Quello che non capisco è: perché PostgreSQL supporta codifiche di più server ? I file di database sono (quasi sempre) incompatibili da una versione PostgreSQL alla successiva, quindi la compatibilità tra versioni non è il problema qui.

UTF-8 è l'unico set di caratteri standard compatibile ASCII in grado di codificare tutti i punti di codice Unicode (se sbaglio, fammi sapere). Sono nel campo che UTF-8 è il miglior set di caratteri, ma sono disposto a sopportare altri set di caratteri universali come UTF-16 e UTF-32.

Credo che tutti i set di caratteri non universali dovrebbero essere deprecati. C'è qualche motivo convincente che non dovrebbero?


4
@mario: la definizione originale di UTF-8 consentiva fino a 6 byte. Successivamente fu limitato artificialmente a coprire solo i personaggi che UTF-16 poteva supportare.
dan04,

6
Almeno PostgreSQL si occupa deliberatamente di più codifiche di caratteri. Fa schifo dover fare i conti con un mix casuale di UTF-8 e windows-1252 perché a qualcuno non importava.
dan04,

5
@ dan04: lavorare con i testi russi in passato era una seccatura, in quanto utilizzavano più codifiche sostanzialmente diverse e di solito semplicemente hackeravano le cose per funzionare utilizzando caratteri diversi (che spesso mentirebbero sulla codifica in uso nei loro metadati). Tutto sommato, un casino orribile. Ho il sospetto che abbiano ripulito, probabilmente passando a UTF-8, perché il numero di richieste di supporto da quella direzione è sceso subito.
Donal Fellows il

3
L'intervallo teorico Unicode è compreso tra 0 e 0x10ffff. Niente di più. Questo è ciò che dice lo standard Unicode. UTF-8 gestisce tutto Unicode e lo farà sempre. Non copre l'intervallo ipotetico di una codifica che non è Unicode, ma copre tutto Unicode.
gnasher729,

Risposte:


16

Da quando hai citato PostgreSQL, posso dire con una certa autorità che il principale motivo killer per cui le codifiche lato server non UTF8 sono supportate in modo così dettagliato è che i giapponesi ne hanno bisogno. Apparentemente, la conversione di andata e ritorno identica tra Unicode e le varie codifiche "legacy" giapponesi non è sempre possibile, e in alcuni casi le tabelle di conversione sono persino diverse tra i fornitori. È davvero sconcertante, ma a quanto pare è così. (L'ampio supporto del set di caratteri è anche uno dei motivi per cui PostgreSQL è così popolare in Giappone.)

Dato che stiamo parlando di un sistema di database, uno dei lavori principali è quello di essere in grado di archiviare e recuperare i dati in modo affidabile, come definito dall'utente, quindi a volte la conversione del set di caratteri con perdita di dati non volerà. Se avessi a che fare con un browser web, diciamo, dove tutto ciò che conta davvero è se il risultato sembra OK, allora potresti probabilmente cavartela con meno codifiche, ma in un sistema di database hai requisiti extra.

Alcuni degli altri motivi menzionati in altre risposte si applicano anche come argomenti a sostegno. Ma fintanto che il giapponese lo pone il veto, il supporto alla configurazione del personaggio non può essere ridotto.


Quindi, a causa di queste codifiche, la conversione del testo in UTF-8 e viceversa è in perdita in generale? Anche se la conversione viene eseguita immediatamente (anziché tra 6 mesi)?
Joey Adams,

Joey Adams: Apparentemente così.
Peter Eisentraut,

3
Google per "Unificazione Han" per capire perché
Petr Viktorin l'

7

Due ovvi motivi: a seconda dei dati che stai memorizzando, la conversione in un formato diverso potrebbe richiedere parecchio tempo e spazio aggiuntivo. Se stai memorizzando 400 megabyte di informazioni, raddoppiare i requisiti di archiviazione non è un grosso problema, ma se stai memorizzando 400 terabyte, questo inizia a significare un po 'di più. Anche la conversione di 400 terabyte di dati da (diciamo) Shift-JIS a UTF-x potrebbe richiedere un po 'di tempo.

Ciò diventa particolarmente difficile se si dispone (ad esempio) di tempi di attività che indicano che il database sarà disponibile per tutti ma, diciamo, 10 minuti in più di un determinato anno e si dispone di un database che viene aggiornato diverse centinaia di volte al secondo. Intendiamoci, è ancora possibile gestire le principali conversioni in una situazione del genere, ma non è qualcosa da intraprendere alla leggera. In alcuni casi, potrebbero essere necessari anni di pianificazione per prepararsi a tale conversione.

Se stavi iniziando con un database che (ad esempio) supportava solo ASCII, potrebbe esserci una buona ragione per discutere se fosse logico aggiungere il supporto per tutte quelle codifiche - ma se le supporti già, c'è poco da guadagnare dall'abbandono supporto per loro.

Nota, in particolare, che probabilmente guadagnerai quasi nulla nel modo di semplificare il codice o qualcosa del genere. Avrebbero comunque bisogno di tutte le routine di conversione per gestire comunque le conversioni tra client e server. Pertanto, eliminare il supporto significherebbe eliminare una (minore) chiamata di funzione nei percorsi "write to disk" e "read from disk", ma poco (se non altro). Se avessi supportato anche due codifiche su disco, non l'avresti nemmeno ottenuto: avresti comunque la chiamata di funzione lì, quindi tutto ciò che faresti davvero sarebbe limitare l'intervallo di codifiche supportate da quella funzione.

Almeno se stavo progettando questo, probabilmente scriverei il core del database per funzionare in UCS-4, e quindi avrei routine di conversione tra il core e il disco e tra il core e l'utente. Userei lo stesso set di routine in entrambi i casi, quindi il percorso più semplice sarebbe quello di consentire all'archiviazione su disco di utilizzare esattamente lo stesso set di codifiche che i client potevano usare.


1
Shift-JIS non è auto-sincronizzante, il che rende la ricerca ingombrante. Si potrebbe ottenere un notevole semplificazione, non lo sostengono.
dan04,

@ dan04: se si dispone già di routine di ricerca / indicizzazione comprovate per Shift-JIS, il passaggio a UTF-8 o persino UCS2 probabilmente migliorerebbe le prestazioni in modo insignificante. Per un nuovo database potresti scegliere una codifica migliore, più comoda e regolare, come UCS2 o UTF-16.
9000

@ dan04: se riuscissi a cavartela senza sostenerlo affatto, guadagneresti un bel po '. Finché lo supporti dai / dai clienti, rimarrai bloccato dalla maggior parte della sua bruttezza ...
Jerry Coffin,

5

Esistono un paio di problemi con la memorizzazione solo di UTF-8 sul server:

  1. Qual è il limite di una VARCHAR(20)colonna? Sono 20 byte o 20 "caratteri" (e in Unicode, cos'è un "carattere" quando si tiene conto della combinazione di caratteri, legature e così via?). Peggio ancora, che dire di CHAR(20)dove debba effettivamente riservare l'intero spazio possibile: credo in MySQL, riserva 4 volte il numero di byte per una colonna codificata UTF-8 (quindi 80 byte per CHAR(20)) solo per gestire il caso peggiore.
  2. È necessario eseguire conversioni di codifica costanti tra la codifica del server e la codifica del client. Potresti sostenere che vuoi smettere di supportare anche più codifiche client, ma a meno che tu non lo faccia, allora tutte le stringhe devono essere convertite continuamente. Se riesci ad abbinare la codifica del tuo server e quella del client, le conversioni non sono necessarie.
  3. Come altri hanno sottolineato, UTF-8 è abbastanza efficiente per l'archiviazione del testo inglese, ma è molto inefficiente per altre lingue, in particolare le lingue dell'Asia orientale. Potresti consentire l'uso UTF-16 o UTF-8 come semi, suppongo. O comprimi il testo, ma ciò rende inefficiente l'indicizzazione e la ricerca.

Detto questo, sono d'accordo con te: le codifiche legacy sono per lo più inutili e Unicode è generalmente la migliore codifica da utilizzare per tutte le nuove applicazioni. Se scrivessi un server di database da zero oggi, supporterei solo Unicode e non supporterei affatto alcuna codifica legacy.

La differenza è che PostgreSQL e la maggior parte degli altri server di database in uso oggi esistevano prima che Unicode fosse un'opzione praticabile. Quindi avevano già il supporto per le codifiche legacy (non erano legacy allora, ovviamente) e non ha molto senso strappare tutto quel codice per ragioni ampiamente ideologiche.


10
"ma è molto inefficiente per altre lingue, in particolare le lingue dell'Asia orientale," Anche nella pratica? Considera questa pagina di Wikipedia in cinese . Anche se mostra un sacco di caratteri cinesi, nella fonte della pagina, i caratteri ASCII li sopraffanno quasi 7: 1.
Joey Adams,

2
Se la N nella colonna CHAR (N) fa parte di un formato identificativo ben definito (ad esempio, un VIN è definito con esattamente 17 caratteri), probabilmente non è necessario combinare caratteri o legature. Altrimenti, allora N è solo un limite arbitrario, che dovrebbe essere interpretato generosamente per evitare di troncare i dati.
dan04,

5
@Joey Adams: questo è vero per HTML e XML in cui il markup stesso costituisce una grande parte del testo (ed è per questo che penso che UTF-8 sia una buona scelta per il web), ma in un database che non memorizzi spesso HTML. Alla fine della giornata, è solo un fattore di due (o meno) differenza, che non è poi così tanto.
Dean Harding,

5
Il punto elenco n. 2 in questa risposta è irrilevante: si applica indipendentemente dall'utilizzo di Unicode. Il punto 3 della pallottola esagera assolutamente l'inefficienza e la sua portata. Allo stesso tempo, questa risposta sottovaluta notevolmente i problemi causati dalle codifiche legacy. È facile supporre che il problema non sia un grosso problema se tutto ciò che usi nella tua vita è l'inglese.
Timwi,

2
@Dean: non sapevo che non fosse permesso commentare una risposta senza pubblicarne una mia.
Timwi,

3

Le codifiche non universali (e specificamente a byte singolo) hanno il loro posto: Sui sistemi che:

  • Non dispone di memoria sufficiente per archiviare il database dei caratteri Unicode.
  • Hanno un font a byte singolo hard-coded nella ROM.
  • Non hanno accesso a Internet per fornire una fonte di file con codifica diversa.

Questo è vero oggi per alcuni tipi di dispositivi integrati. Ma sul desktop e nella sala server, le codifiche non Unicode dovrebbero essere ormai obsolete da tempo.


3
Avevo i computer domestici così. Mi sono sbarazzato della maggior parte di loro nei primi anni '80.
David Thornley,

2

UTF-8 è il migliore per te egocentrico 1 madrelingua inglese. Se fossi giapponese, circa il 99% dei tuoi personaggi richiederebbe 3-4 byte anziché due in UTF-16.

I dialetti non latini soffrono davvero di UTF-8 a livello dimensionale. Non dimenticare che nel giro di pochi anni, la maggior parte dei tuoi clienti potrebbe essere cinese e la scrittura cinese ha milioni di caratteri. Non puoi sostenerlo in modo efficiente con UTF-8.

Altrimenti, lo odio quando ho documenti di testo che non sono in UTF- qualcosa . Spesso mi faccio in quattro se devo avere una codifica corretta. Nel mio libro, le codifiche non Unicode sono morte.

1. Non prendere la parte egocentrica personalmente. Volevo fare un'illustrazione colorata e non intendo proprio questo.


3
@Matthew - 4x è chiaramente 4 volte più grande di x (per x positiva). Non vedo come la notazione asintotica sia rilevante qui. Non ho mai visto un disco rigido pubblicizzato con un tasso di crescita asintotico. Normalmente, le dimensioni rimangono le stesse per tutta la durata dell'unità.
Steve314,

3
Milioni di personaggi non si adatteranno comunque in Unicode. Secondo l'articolo di Wikipedia, ci sono attualmente circa sessantamila personaggi Han. Poiché Unicode non è solo cinese, ciò significa che un discreto numero di caratteri cinesi richiederà quattro byte in UTF-16, che è fino a quando UTF-8 arriva al giorno d'oggi. Sarebbe interessante vedere statistiche sulla lunghezza dei testi cinesi in UTF-8 e UTF-16.
David Thornley,

6
@David:> Il 99% di tutte le scritture giapponese e cinese utilizza caratteri che richiedono solo 2 byte in UTF-16 e 3 in UTF-8. I personaggi che richiedono di più sono molto rari e / o storici.
Timwi,

8
Tieni presente che il giapponese e il cinese generalmente usano meno caratteri per parola. Lavoro con un'app che ha file in lingua inglese, giapponese e cinese di grandi dimensioni, tutti codificati in utf-8. Il file cinese è in realtà il più piccolo, mentre il file giapponese è circa il 15% più grande dell'originale inglese.
Gort il robot il

3
Senza senso. Tutto ciò che richiede due byte in UTF-16 non richiede più di 3 byte in UTF-8. Tutto ciò che è di quattro byte in UTF-8 è di 4 byte in UTF-16. Non ci sono "milioni" di caratteri cinesi e ovviamente non rientrerebbero in 16 bit.
gnasher729,

1

Unicode è sostanzialmente rotto, ed è improbabile che sia mai stato corretto. Deve essere sostituito da qualcosa di meglio, qualcosa di veramente universale. Se qualcosa ha bisogno di essere deprecato, è Unicode.

Esempi di problemi con Unicide:

  • UTF8 è un trucco ragionevole, ma la maggior parte dei software basati su UTF16 è rotta. La maggior parte delle app di Windows che supportano Unicode utilizzano UTF16, incluso il sistema operativo stesso. Il problema più comune non supporta più del piano di base, vale a dire caratteri multi-parola.

  • L'unificazione Han è un disastro immeritato. È impossibile mescolare il testo giapponese / cinese / coreano in un singolo documento senza metadati aggiuntivi e difficile individuare quale font deve essere utilizzato.

  • I personaggi combinati sono un altro disastro. Gli schemi di codifica più sensibili associano un carattere a un codice, il che rende l'elaborazione delle stringhe relativamente sana. Unicode no. Unicode non è nemmeno coerente - i personaggi Han sono per lo più combinazioni, ma non sono codificati come tali, dove sono i caratteri combinatori europei.

  • I nomi di alcune persone non possono essere scritti correttamente in Unicode o sono molto inclini a essere visualizzati in modo errato a causa dei problemi sopra menzionati. Ciò può avere gravi conseguenze, ad esempio quando si tenta di salire a bordo di un aereo con un passaporto che non corrisponde a ciò che è (erroneamente) stampato sul biglietto.

A causa di questi problemi e altro, molti software non inglesi non possono usare Unicode e si basano su codifiche di caratteri locali. Ciò è particolarmente comune con il software giapponese e cinese.

Idealmente, Unicode dovrebbe essere deprecato. La codifica dei caratteri TRON è un sostituto abbastanza buono per Unicode e ampiamente compatibile con i software esistenti che non verranno aggiornati.


La tua affermazione che è impossibile mescolare le diverse varianti di caratteri (giapponese / coreano / cinese) sembra essere obsoleta da 15 anni, lo standard Unicode 3.2 al 2002. Unicode supporta selettori di varianti, punti di codice che dopo un punto di codice han specificano esplicitamente quale forma dovrebbe essere visualizzato. Anche i caratteri combinatori sono specificati sia come "combinazione di segni diacritici" con caratteri di base (a °) e glifi speciali (å), il processo di conversione viceversa è "normalizzazione". Quindi no, Unicode non è sostanzialmente rotto.
Thorsten S.

Illustri molti dei difetti. Alcune lingue usano caratteri combinatori, altre no, e Unicode non può decidere quale preferisce. Come ho sottolineato, la maggior parte dei software che afferma di supportare Unicode non comprende comunque questi problemi e li mostrerà errati anche con i selettori. I programmatori non dovrebbero essere esperti di lingua, che è l'altro difetto fondamentale di Unicode.
utente

0

Forse per scrivere, ma non per leggere.

Esiste un sacco di contenuto esistente che utilizza tali codifiche e alcune codifiche come base64 non vanno da nessuna parte perché alcuni protocolli di testo obbligano questi come modi per incorporare i dati binari.

Un vero problema è il rilevamento automatico delle codifiche che porta a buchi di sicurezza. Non mi dispiacerebbe vedere alcune oscure codifiche come UTF-7 semplicemente scomparire.

Il rilevamento automatico tende inoltre a gestire male il contenuto prodotto concatenando ingenuamente stringhe di byte.


7
Base64 non è una codifica di caratteri.
dan04,

0

Sono d'accordo che la codifica dei caratteri predefinita per database e nuove applicazioni dovrebbe essere una sorta di variante UTF. Personalmente opterei per UTF-16 poiché sembra essere un ragionevole compromesso su spazio e complessità (più che su UTF-8). Detto questo, alcune codifiche di caratteri hanno ancora senso in alcuni casi.

  • Se stai memorizzando / trasferendo testo base64, hai solo bisogno di ASCII e puoi persino scappare con protocolli codificati a 7 bit come la posta elettronica. Il sovraccarico aggiuntivo di UTF-8 non è necessario.
  • Diversi file e dati esistenti si basano su queste codifiche di caratteri precedenti, è importante poterle leggere.

Si noti che esistono 4 algoritmi di normalizzazione UTF standard. Se sei preoccupato per i caratteri con più punti di codice, puoi utilizzare uno dei due algoritmi di normalizzazione che li comprime nel carattere di punto di codice singolo equivalente. La differenza tra loro ha a che fare con l'equivalenza logica rispetto all'equivalenza fisica dei caratteri.


1
I downvoter possono dire perché hanno effettuato il downvoting?
Berin Loritsch,

3
Non ho effettuato il downgrade, ma l'intero punto di base64 è trasferire i dati binari lungo un canale di testo. Se potessi scegliere quale codifica usare su quel canale, non utilizzeresti affatto una codifica di testo. Anche se il tuo canale è realmente ASCII semplice, la base 64 utilizza solo 6 bit su 7, un sovraccarico significativo già.
Steve314,

Spero che qualcuno non abbia semplicemente letto i punti elenco. Quelle erano le eccezioni all'uso di UTF. E non si è corretti sulla base 64 utilizzando solo 6 byte su 8. Il primo set di "caratteri" ASCII sono caratteri di controllo non stampabili, che forza alcuni dei caratteri in base64 a usare 7 degli 8 byte. Evita di proposito il bit alto perché non è garantito che tutti quei caratteri esistano in ogni tabella di codici, mentre i caratteri da 0-127 lo sono.
Berin Loritsch,

2
@Berin - (1) no, ma quella roba "Sono d'accordo" non è molto senza i punti elenco e (2) la base 64 ha 64 "cifre". 64 cifre valgono 6 bit, perché 2 ^ 6 == 64. Il modo in cui lo rappresenti in uno spazio di codice a 7 bit (o 8 bit, o anche 8 byte, se necessario) è separato dalla quantità di dati effettivamente presenti. Evitare i caratteri non stampabili, ecc. È la ragione dell'overhead - non significa che l'overhead non esista. Scegli un canale progettato per i dati binari e quel sovraccarico non c'è.
Steve314,

3
Tieni presente che Base64 è stato inventato per gestire l'invio di dati binari su un canale di solo testo. È noto per essere inefficiente (espansione 3: 4), ma affronta le limitazioni tecniche in alcune opzioni di trasporto. I legacy sarebbero i forum di posta elettronica e UseNet, ma un'applicazione più moderna incorporerebbe i dati binari in XML. A volte non esiste il canale corretto e devi superare i limiti di quelli esistenti.
Berin Loritsch,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.