UTF-8 (ve belki UTF-16 / UTF-32) dışındaki karakter kodlamaları kaldırılmalıdır mı?


31

Bir evcil hayvan eşim, karakter kümesi desteği için kod dağları bulunan birçok yazılım projesine bakıyor. Beni yanlış anlamayın, ben tamamen uyumluluk için varım ve metin editörlerinin dosyaları birden çok karakter setinde açmanıza ve kaydetmenize izin vermesinden memnunum Beni rahatsız eden şey, evrensel olmayan karakter kodlamalarının çoğalmasının “sorun” değil, “uygun Unicode desteği” olarak etiketlenmesidir.

Örneğin, PostgreSQL ve karakter seti desteğini seçmeme izin verin . PostgreSQL iki tip kodlama ile ilgilenir:

  • İstemci kodlaması: İstemci ile sunucu arasındaki iletişimde kullanılır.
  • Sunucu kodlaması: Metni dahili olarak veritabanında saklamak için kullanılır.

Neden çok sayıda müşteri kodlamasını desteklemenin iyi bir şey olduğunu anlayabiliyorum. UTF-8'de çalışmayan müşterilerin, dönüşüm gerçekleştirmeye gerek kalmadan PostgreSQL ile iletişim kurmasını sağlar. Ne anlamadım: PostgreSQL neden birden çok sunucu kodlamasını destekliyor ? Veritabanı dosyaları (neredeyse her zaman) bir PostgreSQL sürümünden diğerine uyumsuzdur, bu nedenle çapraz sürüm uyumluluğu burada sorun değildir.

UTF-8, tüm Unicode kod noktalarını kodlayabilen tek standart, ASCII uyumlu karakter setidir (yanılıyorsam bana bildirin). UTF-8'in en iyi karakter kümesi olduğu kampındayım , ancak UTF-16 ve UTF-32 gibi diğer evrensel karakter setlerine katılıyorum.

Tüm evrensel olmayan karakter setlerinin kullanımdan kaldırılması gerektiğine inanıyorum. Olmaması için zorlayıcı bir sebep var mı?


4
@ mario: UTF-8'in orijinal tanımı 6 bayta kadar izin verdi. Daha sonra yapay olarak sadece UTF-16'nın destekleyebileceği karakterleri kapsaması kısıtlandı.
dan04,

6
En azından PostgreSQL kasten birden fazla karakter kodlamasıyla ilgilenir. Birisi umursamadı çünkü UTF-8 ve windows-1252'nin rastgele bir karışımıyla uğraşmak zorunda kaldı.
dan04,

5
@ dan04: Rusça metinlerle çalışmak eskiden çok farklı olan ve genellikle farklı yazı tiplerini kullanarak (genellikle meta verilerinde kullanılan kodlama hakkında yatar) çalışacak şeyleri hackleyen birden fazla kodlama kullandıkları için bir acıydı. Sonuçta, korkunç bir karışıklık. Yine de - muhtemelen UTF-8'e geçerek - temizlediklerinden şüpheleniyorum çünkü bu yöndeki destek taleplerinin sayısı hemen düştü.
Donal Fellows

3
Teorik Unicode aralığı 0 ile 0x10ffff arasındadır. Daha fazlası değil. Unicode standardının söylediği de bu. UTF-8 Unicode'un tamamını idare eder ve daima kullanır. Unicode olmayan bir kodlamanın varsayımsal kapsamını kapsamaz, ancak tüm Unicode'u kapsar.
gnasher729

Yanıtlar:


16

PostgreSQL’den bahsettiğinizden, bazı otoritelerle UTF8 dışındaki sunucu tarafı kodlamaların desteklenmesinin ana katilin neden bu kadar ayrıntılı olduğunu söyleyebildiğimi söyleyebilirim. Görünüşe göre Unicode ve çeşitli Japonca "eski" kodlamaları arasındaki özdeş gidiş dönüş dönüşümü her zaman mümkün değildir ve bazı durumlarda dönüşüm tabloları satıcılar arasında bile farklıdır. Gerçekten şaşırtıcı, ama görünüşe göre öyle. (Kapsamlı karakter kümesi desteği ayrıca PostgreSQL'in Japonya'da bu kadar popüler olmasının sebeplerinden biridir.)

Bir veritabanı sisteminden bahsettiğimizden, ana işlerden biri, kullanıcı tarafından tanımlandığı şekilde güvenilir bir şekilde veri depolayabilmesi ve alabilmesidir; bu nedenle, kayıp karakter kümesi dönüşümü bazen uçmaz. Bir web tarayıcısıyla ilgileniyorsanız, önemli olan tek şey, sonucun iyi görünüp görünmediğidir , o zaman muhtemelen daha az kodlamayı desteklemekten kurtulabilirsiniz, ancak bir veritabanı sisteminde ekstra gereksinimleriniz olabilir.

Diğer cevaplarda belirtilen diğer nedenlerden bazıları da destekleyici argümanlar olarak uygulanır. Ancak Japon veto ettiği sürece, karakter kurulum desteği azaltılamaz.


Yani, bu kodlamalar nedeniyle, metnin UTF-8 ve arkasına dönüştürülmesi genel olarak kayıp mıdır? Geri dönüşüm hemen yapılsa bile (bundan 6 ay sonra)?
Joey Adams

Joey Adams: Görünüşe göre öyle.
Peter Eisentraut

3
Nedenini görmek için "Han birleştirme" için Google
Petr Viktorin

7

İki belirgin neden: Sakladığınız verilere bağlı olarak, farklı bir formata dönüştürmek biraz zaman alabilir ve ekstra yer alabilir. 400 megabayt bilgi saklıyorsanız, depolama gereksinimlerini ikiye katlamak önemli değildir - ancak 400 terabayt depolarsanız, biraz daha fazla şey ifade etmeye başlar. 400 terabayt veriyi (örneğin) Shift-JIS'den UTF-x'e dönüştürmek de biraz zaman alabilir.

Bu, örneğin (eğer) veritabanının herkes için uygun olacağını söyleyen çalışma süresinin garantisi varsa (örneğin, herhangi bir yılın 10 dakikası dışındaysa ve saniyede birkaç kez güncellenen bir veritabanınız varsa) özellikle zorlaşır. Unutmayın, böyle bir durumda büyük dönüşümleri yönetmek hala mümkün , ancak hafifçe yapılması gereken bir şey değil . Bazı durumlarda, böyle bir dönüşüme hazırlanmak için yıllar süren planlamayı kolayca yapabilirsiniz .

(Örneğin) yalnızca ASCII'yi destekleyen bir veritabanıyla başlıyorsanız, tüm bu kodlamalar için destek eklemenin mantıklı olup olmadığını tartışmak için iyi bir neden olabilir ; onlar için destek.

Özellikle, kodu basitleştirme yolunda veya hiçbir şeyden başka bir şey elde edemeyeceğinizi unutmayın. Yine de müşteri ve sunucu arasındaki dönüşümlerle başa çıkmak için tüm dönüşüm rutinlerine ihtiyaçları var. Dolayısıyla, desteğin bırakılması, "diske yaz" ve "diskten oku" yollarına bir (küçük) işlev çağrısının bırakılması, ancak çok az (başka bir şey varsa) anlamına gelir. Eğer diskteki iki kodlamayı bile destekleseydiniz , bunu bile elde edemezsiniz - hala orada işlev çağrısı yapacaktınız, yani gerçekten tek yapmanız gereken, bu işlev tarafından desteklenen kodlama aralıklarını kısıtlamak olacaktır.

En azından bunu tasarlıyor olsaydım, muhtemelen veritabanının çekirdeğini UCS-4'te çalışmak üzere yazardım ve sonra çekirdek ile disk arasında ve çekirdek ile kullanıcı arasında dönüşüm rutinleri kullanırdım. Bu yüzden, her iki durumda da rutinleri aynı seti kullanmak istiyorum basit rota disk depolama kullanmasına izin vermek olacaktır tam olarak istemcilerin kullanmak için izin verildi olarak kodlamaların aynı seti.


1
Shift-JIS, kendi kendine senkronize olmayan, arama yapmayı zorlaştırıyor. Sen olur desteklememesi tarafından önemli basitleştirilmesi kazanırlar.
dan04 6

@ dan04: Shift-JIS için zaten kanıtlanmış arama / dizin oluşturma yordamlarınız varsa, UTF-8'e veya hatta UCS2'ye geçmek muhtemelen performansı önemsiz şekilde artıracaktır. Bir İçin Yeni veritabanı Eğer UCS2 veya UTF-16 gibi daha iyi, daha rahat ve düzenli kodlamayı tercih edebilir.
9000

@ dan04: Eğer desteklememekle kaçabilirsen, biraz kazanırsın. Müşterilerden gelip gelmesini desteklediğin sürece, çirkinliğinin büyük kısmı ile sıkışıp kalacaksın ...
Jerry Coffin,

5

Sunucuya yalnızca UTF-8 depolamakla ilgili birkaç sorun var:

  1. Bir VARCHAR(20)sütunun limiti nedir ? Bu 20 bayt mı, yoksa 20 "karakter" mi (ve Unicode'da karakterleri, bitişik harfleri vb. Birleştirirken bir "karakter" nedir?). Daha da kötüsü, CHAR(20)gerçekte tüm olası alanı nereye ayırması gerektiği hakkında : Peki CHAR(20), en kötü durumla başa çıkmak için UTF-8 kodlu bir sütun için (yani 80 bayt ) 4 kat bayt sayısını saklı tutar .
  2. Sunucu kodlaması ile müşteri kodlamanız arasında sabit kodlama dönüşümleri yapmanız gerekir. Birden fazla müşteri kodlamasını desteklemeyi durdurmak istediğinizi de iddia edebilirsiniz, ancak bunu yapmazsanız, tüm dizelerin her zaman dönüştürülmesi gerekir. Sunucu kodlamanız ve müşteri kodlamanızla eşleşebilirseniz, dönüşüm gerekmez.
  3. Diğerlerinin de belirttiği gibi, UTF-8 İngilizce metinleri saklamak için oldukça verimlidir, ancak diğer diller için - özellikle Doğu Asya dilleri için çok verimsizdir . Sanırım UTF-16 veya UTF-8'in uygun olduğunu düşünebilirsiniz. Veya metni sıkıştırın, ancak bu indekslemeyi ve aramayı verimsiz hale getirir.

Bunları söyledikten sonra, sana katılıyorum: eski kodlamalar çoğunlukla anlamsız ve Unicode genellikle tüm yeni uygulamalar için kullanılacak en iyi kodlama. Bugün sıfırdan bir veritabanı sunucusu yazıyor olsaydım, sadece Unicode'u ve eski kodlamaları desteklemeyecektim.

Fark PostgreSQL ve kullanımda diğer birçok veritabanı sunucuları bugün etrafında olduğudur önce Unicode uygun bir seçenek oldu. Bu yüzden zaten eski kodlamaları desteklediler (tabii ki o zamanlar eski değillerdi) ve tüm bu kodları büyük ölçüde ideolojik nedenlerle sökmek için çok fazla bir neden yok.


10
"ancak diğer diller için çok verimsiz - özellikle doğu Asya dilleri," Pratikte bile? Bu Çince Vikipedi sayfasını göz önünde bulundurun . Çok fazla Çince karakter göstermesine rağmen, sayfa kaynağında, ASCII karakterleri onları neredeyse 7: 1 oranında bastırıyor.
Joey Adams

2
CHAR (N) sütunundaki N, iyi tanımlanmış bir tanımlayıcı biçiminin bir parçasıysa (örneğin, bir VIN tam olarak 17 karakter olarak tanımlanır), o zaman muhtemelen birleştirme karakterlerine veya bitişik harflere gerek duymaz. Olmazsa, N sadece keyfi bir sınırlamadır ve verilerin kesilmesinden kaçınmak için cömertçe yorumlanmalıdır.
dan04,

5
@Joey Adams: işaretlemenin kendisinin metnin büyük bir bölümünü oluşturduğu HTML ve XML için bu doğru (ve bu yüzden UTF-8'in web için iyi bir seçim olduğunu düşünüyorum), ancak sık sık saklamadığınız bir veritabanında HTML. Günün sonunda, bu aslında iki değil (ya da daha az) bir fark faktörüdür.
Dean Harding,

5
Bu cevaptaki madde işareti # 2 anlamsızdır: Unicode'un kullanılıp kullanılmadığını uygular. Madde # 3, verimsizliği ve kapsamını kesinlikle abartıyor. Aynı zamanda, bu cevap eski kodlamaların neden olduğu sorunları büyük ölçüde vurgulamaktadır. Hayatınızda kullandığınız tek şey İngilizce ise, sorunun bu kadar büyük bir mesele olmadığını kabul etmek kolaydır.
Timwi

2
@ Dean: Benden birini göndermeden bir cevap hakkında yorum yapmasına izin verilmediğini bilmiyordum.
Timwi

3

Evrensel olmayan (ve özellikle tek baytlı) kodlamalar kendi yerlerine sahiptir: Sistemlerde:

  • Unicode Karakter Veritabanını depolamak için yeterli hafızaya sahip değilsiniz.
  • ROM'da kodlanmış tek baytlık bir font var.
  • Farklı kodlanmış dosya kaynağı sağlamak için İnternet erişiminiz yok.

Bu, bazı gömülü aygıt türleri için bugün geçerlidir. Ancak masaüstünde ve sunucu odasında, Unicode olmayan kodlamalar şimdiye kadar eski olmalıdır .


3
Evde böyle bir bilgisayar vardı. 80'lerin başlarında çoğundan kurtuldum.
David Thornley

2

Sizin için en iyisi UTF-8, 1 merkezli konuşmacıdır. Japon olsaydınız karakterinizin yaklaşık% 99'u UTF-16'da iki yerine 3-4 bayt alırdı.

Latince olmayan lehçeler, boyut düzeyinde gerçekten UTF-8'den muzdariptir. Unutmayın, birkaç yıl içinde müşterilerinizin çoğu Çince olabilir ve Çince yazının milyonlarca karakteri vardır. UTF-8 ile bunu verimli bir şekilde sürdüremezsiniz.

Ben UTF-olmayan metin belgelerini varken Aksi takdirde, ben nefret şey . Doğru kodlamaya ihtiyacım olursa, sık sık yolumdan çekileceğim. Kitabımda Unicode olmayan kodlamalar öldü.

1. Merkezli kısmı kişisel olarak almayın. Renkli bir örnek yapmak istedim ve gerçekten demek istemedim.


3
@Matthew - 4x açıkça x'ten 4 kat daha büyüktür (pozitif x için). Asimptotik gösterimin burada ne kadar önemli olduğunu anlamıyorum. Asimptotik büyüme oranı olan bir sabit disk görmedim. Normalde, boyut sürücünün ömrü boyunca aynı kalır.
Steve314

3
Unicode'a zaten milyonlarca karakter sığmayacak. Wikipedia makalesine göre, şu anda yaklaşık altmış bin Han karakter var. Unicode yalnızca Çince olmadığından, bugünlerde UTF-8'in alabileceği kadar, çok sayıda Çince karakterin UTF-16'da dört bayt alacağı anlamına gelir. UTF-8 ve UTF-16’da Çince metinlerin uzunluğuyla ilgili istatistikleri görmek ilginç olurdu.
David Thornley

6
@David:> Tüm Japonca ve Çince yazıların% 99'u UTF-16'da yalnızca 2 bayt ve UTF-8'de 3 karakter kullanan karakterleri kullanır. Daha fazlasını gerektiren karakterler çok nadir ve / veya tarihseldir.
Timwi

8
Japonca ve Çince'nin genellikle kelime başına daha az karakter kullandığını unutmayın. Hepsi utf-8 ile kodlanmış İngilizce, Japonca ve Çince dillerinde geniş dil dosyaları olan bir uygulama ile çalışıyorum. Çince dosya aslında en küçük, Japonca dosya ise İngilizce orijinalinden yaklaşık% 15 daha büyük.
Robotu

3
Saçmalık. UTF-16'da iki bayt alan herhangi bir şey UTF-8'de en fazla 3 bayt alır. UTF-8’de dört bayt olan her şey UTF-16’da 4 bayttır. Çince karakter "milyonlarca" yoktur ve açıkçası 16 bit sığmazlar.
gnasher729

1

Unicode temelde bozuldu ve düzeltilmesi pek mümkün değil. Daha iyi bir şeyle değiştirilmesi gerekiyor, gerçekten evrensel bir şey. Bir şeylerin kullanımdan kaldırılması gerekiyorsa, Unicode'dur.

Unicide ile ilgili örnek konular:

  • UTF8 makul bir kesmektir, ancak çoğu UTF16 tabanlı yazılım bozulur. Unicode'u destekleyen çoğu Windows uygulaması, işletim sisteminin kendisi de dahil olmak üzere UTF16'yı kullanır. En yaygın sorun, temel düzlemden daha fazlasını, yani çok kelimeli karakterleri desteklememesidir.

  • Han'ın birleşmesi onaylanmamış bir felakettir. Japonca / Çince / Korece metinleri tek bir belgede fazladan meta veri olmadan karıştırmak imkansızdır ve hangi fontun kullanılması gerektiğini belirlemek zor.

  • Kombinasyonel karakterler başka bir felakettir. Daha mantıklı kodlama şemaları, bir karakter dizisini bir koda eşler, bu da işlem dizelerinin nispeten aklı başında olmasını sağlar. Unicode değil. Unicode bile tutarlı değil - Han karakterleri çoğunlukla kombinasyonlar, ancak Avrupa kombinasyon karakterleri olduğu gibi kodlanmadı.

  • Bazı kişilerin adları Unicode'da doğru bir şekilde yazılamıyor veya yukarıda belirtilen sorunlar nedeniyle yanlış yapılmaya meyilli. Bunun, örneğin, biletin üzerine basılanla (yanlış) uyuşmayan pasaportlu bir uçağa binmeye çalışırken ciddi sonuçları olabilir.

Bu sorunlar ve daha fazlası nedeniyle, çoğu İngilizce olmayan yazılım Unicode kullanamaz ve yerel karakter kodlamasına güvenir. Bu, özellikle Japonca ve Çince yazılımlarda yaygındır.

İdeal olarak, Unicode kullanımdan kaldırılmalıdır. TRON karakter kodlaması Unicode için oldukça iyi bir alternatiftir ve güncellenmeyecek olan mevcut yazılım için büyük ölçüde uyumludur.


Farklı karakter varyantlarını (Japonca / Korece / Çince) karıştırmanın imkansız olduğu iddiası, 15 yıldan beri 2002’deki Unicode 3.2 standardı olarak modası geçmiş gibi görünüyor. görüntülenmeli. Ayrıca, birleştirme karakterleri hem "aksan işaretleri" temel karakterlerle (a °) hem de özel gliflerle (å) birleştirme olarak belirtilir; bunun tersi de "normalizasyon" olur. Yani, hayır, Unicode temelde bozuk değil.
Thorsten S.

Kusurların çoğunu resimlersiniz. Bazı diller birleşik karakterler kullanır, bazıları kullanmaz ve Unicode hangisini tercih ettiğine karar veremez. Belirttiğim gibi, Unicode'u desteklediğini iddia eden çoğu yazılım bu sorunları zaten anlamıyor ve seçicilerde bile yanlış gösterecek. Programcıların Unicode'daki diğer temel hata olan dil uzmanları olması beklenmemelidir.
kullanıcı

0

Belki yazmak için, ama okumak için değil.

Bu kodlamaları kullanan birçok içerik var ve base64 gibi bazı kodlamalar hiçbir yere gitmiyor çünkü bazı metin protokolleri bunları ikili verileri gömmek için zorunlu kılar.

Asıl sorun, güvenlik deliklerine yol açan kodlamaların otomatik olarak algılanmasıdır. UTF-7 gibi bazı gizli kodlamalar sadece kayboluyor görmek sakıncası olmaz .

Otomatik algılama ayrıca, bayt dizelerinin saf bir şekilde birleştirilmesiyle üretilen içerikle de kötü başa çıkma eğilimindedir.


7
Base64 bir karakter kodlaması değil.
dan04,

0

Veritabanları ve yeni uygulamalar için varsayılan karakter kodlamasının bir tür UTF değişkeni olması gerektiğine katılıyorum . Ben kişisel olarak UTF-16'yı tercih ederim, çünkü mekan ve karmaşıklık konusunda makul bir tradeoff gibi görünüyor (UTF-8'den çok). Bununla birlikte, bazı karakter kodlamaları bazı durumlarda hala anlamlıdır.

  • Base64 metnini saklıyorsanız / aktarıyorsanız, yalnızca ASCII'ye ihtiyacınız vardır ve e-posta gibi 7 bitlik kodlanmış protokollerden bile kurtulabilirsiniz. UTF-8'in ek yükü gereksizdir.
  • Birkaç eski dosya ve mevcut veri bu eski karakter kodlamaları üzerine kuruludur, bunları okuyabilmek önemlidir.

4 standart UTF normalizasyon algoritması olduğunu unutmayın. Çoklu kod noktası karakterleriyle ilgileniyorsanız, bunları eşdeğer tek kod noktası karakterine daraltan iki normalleştirme algoritmasından birini kullanabilirsiniz. Aralarındaki fark, karakterlerin fiziksel denkliği ile mantıksal denklik arasındadır.


1
Katılanlar lütfen neden reddedildiklerini söyleyebilir mi?
Berin Loritsch

3
Aşağı oylamadım, ama base64'ün amacı ikili veriyi bir metin kanalından aktarmak. O kanalda hangi kodlamanın kullanılacağını seçebilseniz, hiç bir metin kodlaması kullanmazsınız. Kanalınız gerçekten düz ASCII olsa bile, taban 64 zaten 7 bitden 6'sını kullanıyor - zaten önemli bir yük.
Steve314,

Umarım birileri sadece kurşun noktalarını okumamış. Bunlar UTF kullanmanın istisnasıydı. Ve yalnızca 64'ü yalnızca 8 bayttan 6'sı kullanarak üs 64 konusunda yanılıyorsunuz. İlk ASCII "karakterleri" dizisi basılabilir olmayan kontrol karakterleridir, bu da base64'deki bazı karakterleri 8 bayttan 7'sini kullanmaya zorlar. Kasten yüksek biti ortadan kaldırır, çünkü tüm karakterlerin 0-127 arası karakterler olsalar da her kod sayfasında yer alması garanti edilmez.
Berin Loritsch

2
@Berin - (1) hayır, ama "Katılıyorum" öğelerinin kurşun işaretleri olmadan fazla olmadığı ve (2) üs 64'ün 64 "basamağı" olduğu söylenir. 64 hane 6 bittir, çünkü 2 ^ 6 == 64. 7 bitlik bir kod boşluğunda (veya 8 bit, hatta gerekirse 8 byte) temsil etme şekliniz, gerçekte ne kadar veri bulunduğundan ayrıdır. Yazdırılmayan karakterlerden vb. Kaçınılması, ek yükün sebebidir - ek yükün var olmadığı anlamına gelmez. İkili veriler için tasarlanmış bir kanal seçin ve bu ek yük orada değil.
Steve314

3
Base64'ün sadece metin kanalı üzerinden ikili veri gönderme ile ilgilenmek için icat edildiğini unutmayın. Verimsiz (3: 4 genişleme) olduğu bilinmektedir, ancak bazı ulaştırma seçeneklerinde teknik kısıtlamalar ile ilgilenmektedir. Eski e-posta ve UseNet forumları olurdu, ancak daha modern bir uygulama, ikili veriyi XML'e katıştırıyordu. Bazen uygun kanal yoktur ve mevcut olanların sınırlarını aşmanız gerekir.
Berin Loritsch
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.