Latin-1 UTF-8 üzerinden veritabanı konfigürasyonunda kullanılmalı mıdır?


65

MySQL'i çalıştığım şirkette kullanıyoruz ve Ruby on Rails'i kullanarak hem müşteriye yönelik hem de dahili uygulamalar geliştiriyoruz.

Burada çalışmaya başladığımda daha önce hiç karşılaşmadığım bir problemle karşılaştım; Üretim sunucusundaki veritabanı Latin-1 olarak ayarlanmıştır; bu, kullanıcının UTF-8 karakterlerini kopyalayıp yapıştırdığı kullanıcı girişi olduğunda MySQL geminin bir istisna atacağı anlamına gelir.

Patronum bu "kötü karakterleri" çağırıyor çünkü çoğu yazdırılamaz karakter ve onları çıkarmamız gerektiğini söylüyor. Bunu yapmanın birkaç yolunu buldum, ama sonunda bir UTF-8 karakterinin gerekli olduğu bir durumda sona erdik. Artı, bu biraz zor, özellikle de bu konuda okuduğum tek çözüm gibi görünüyor çünkü veritabanını sadece UTF-8'e ayarlamak (bana mantıklı geliyor).

Latin-1'e yapıştırdığımı duyduğum tek argüman, yazdırılamayan UTF-8 karakterlerine izin vermenin MySQL'de metin / tam metin aramalarını karıştırdığıdır. Bu gerçekten doğru mu?

Latin-1’i UTF-8’de kullanması gereken başka nedenler var mı? Benim anlayışıma göre üstün ve daha yaygın hale geliyor.


4
@ jon LATIN-1 İngilizce'ye özgü değildir . Yanılmıyorsam İspanyolca mükemmel yanı sıra Fransızcayı da içeriyor.
Darkhogg,

4
@Darkhog: Latince1 gerçekten İngilizceye özgü değildir, fakat esasen batı-Avrupa alfabeleriyle sınırlıdır.
Bart van Ingen Schenau

16
Modern bir sistemde UTF-8 yerine Latince 1 kullanmanın tek faydası sabotajdır. Tabii ki bu sadece sistemin sahibine veya geliştiricisine değil, sabote ediciye ve sadakatini kim üstlenirse bir faydadır.
Jon Hanna,

13
Veritabanınızın Euro sembolünü, hatta adımı (דותן) tutamaması çok kötü.
dotancohen

20
latin-1 olmayan karakterleri "kopyala ve yapıştır" kullanıcı? unicode'u sadece yaramaz ineklerin ilgilendiği anlamsız, saçma bir şey olarak görmeyin. Bize oldukça çok türü düzenli olarak latin-1 sığmaz karakterleri - ı bile ♥, birçok insan olmayan avrupa dilleri konuşan duymak
Eevee

Yanıtlar:


131

Unicode kesinlikle zordur ve UTF-8 kodlaması birkaç uygunsuz özelliğe sahiptir. Bununla birlikte, UTF-8, ASCII, Latin-1, UCS-2 ve UTF-16'yı geçerek web üzerinde fiili standart kodlama haline gelmiştir. Hemen her yerde UTF-8 kullanmak .

Unicode'u desteklemenizin en önemli nedeni, kullanıcı girişi hakkında gereksiz varsayımlarda bulunmamanız gerektiğidir. Etki alanınızın ne olduğu hakkında hiçbir fikrim yok, ancak İbranice kullanıcı adları, Çin ile ilgili bir blog yazısı, Emoji ile ilgili bir yorum ya da basitçe iyi yazılmış bir metin - “bu” gibi - mümkün olmalı… Ah, bunlar tipografik olarak doğru tırnak işaretleridi ( “”yerine ""), geniş çizgi ve İngilizce metinde yaygın olan ancak ASCII veya Latin-1 tarafından desteklenmeyen karakterler olan bir üç nokta. Bu yüzden diğer senaryoları desteklememek sadece diğer kültürler için büyük bir f * ck değildir, fakat Latin-1'e sadık kalmak, düzgün İngilizce yazmanıza bile izin vermez.

Unicode'un sadece “kötü karakterlere” izin verdiği fikri yanlıştır. Evet, metin gerçekten karmaşık ve Unicode bunu senden saklamayacak. Patronunuz gibi bir temel kod anoktasının, örneğin gibi bir görsel karakter oluşturmak için diakritikleri temsil eden sonraki kod noktalarıyla değiştirildiği , oluşturulmuş karakterleri düşünüyor olabilir á. Bu, bir tür normalizasyon yaparsanız, arama yapmaya çalışırken gerçekten işe yaramaz. Örneğin, tüm metinleri, eğer varsa, bu tür kompozisyonları önceden oluşturulmuş formlarına daraltan NFC formunda saklayabilirsiniz. Arama yaparken, metindeki tüm beste karakterlerini de sorabilirsiniz, ancak bu, bazı dillerde anlamlarını büyük ölçüde değiştirebilir.

Unicode ayrıca çok sayıda yazdırılamaz karakter ekler - ancak ASCII bile bunlardan çok sayıda içerir. İpin ortasındaki NUL ile ilgilenir misin? “Dosya Ayırıcı” 0x1C nasıl? Bunların yarısını hiç görmedim . Latince-1, kelime sonu fırsatlarını gösteren yumuşak bir kısa çizgi ekler ancak başka şekilde görünmez. Bu tam metin aramanızı da bozuyor mu? Başka bir deyişle, ASCII ve Latin-1 bile, yalnızca yazdırılabilir bir metin olduğunu varsayarsanız, girdilerinizi tamamen kırmanıza izin verir!


8
Veritabanı açısından bakıldığında, bu karakterlerin bazılarına metin türü alanında izin verilmemektedir / verilmemelidir (text / varchar / char / etc.). MySQL gelmez bu veri türleri null karakter kullanılabilir ancak PostgreSQL gibi diğer veritabanları yok. Bu tür karakterleri saklayabilmek için BLOB (MySQL) veya BYTEA (PostgreSQL) kullanmanız gerekir.
cimmanon

15
"Latince-1'e yapıştırmak düzgün İngilizce yazmanıza bile izin vermez" Bu iyi bir şey, aksi halde unicode daha güçlü bir şekilde direnir. ;-)
Deduplicator

3
@ PaŭloEbermann Gömülü NUL karakterleri, verilerinizin yalnızca bir dize değil, ikili bir blob olduğu anlamına gelir. NUL'lar garip bir örnekti, çünkü UTF-8'in \0kodun bir dize ortasında durmadığından emin olmak için UTF-8'in çok baytlı kodlamanın bir parçası olarak bayt kullanmaktan kaçındığını düşünüyorum .
Peter Cordes

7
Tüm unicode karakterler basılabilirdir - sadece doğru yazı tipine ihtiyacınız var :-)
James Anderson

4
@JamesAnderson yazı tipi daha sonra yanlış ve bozuk olurdu. en.wikipedia.org/wiki/Unicode_control_characters
djechlin

62

Teknik sorunun ötesinde, patronunuzun mevcut standartlara ayak uydurabilecek zamanı olmadığını düşünüyorum.

Duruşu öğle yemeğinde tamamen dışarıda olmadığı için, sadece tarihli, bu konuyu tartışırken (ve tartışmak zorunda değilken tartışmayı hatırlamanız gerekir) konumuna saygı duyun ve UTF-8 ile ilgili endişeleri üzerinde çalışmaya çalışın. Temel meselenin teknik bir mesele olmadığını ve belli düzeyde bir yumuşak beceri müzakeresi gerektirebileceğini düşünüyorum.


6
Daha fazla onaylayamadım. Aslında kendi cevabımda, bu konuda çok önemli olabilecek “insan tarafını” tamamen göz ardı ettiğime pişmanım. Keşke birden fazla kez oy kullanabilseydim :-)
LSerni

2
dışında latin-1 herşeyi çağırarak bad characterbunlar ve düşünme non-printableolduğunu just out-datedsize?
njzk2

2
Asıl mesele, "Ele aldığımız teknik bir konu mu?" OP'nin patronunun okula gittiğine ve bunun öğretildiğine veya teknik el kitabı / dergi okuduğuna ve bu sonuca vardığına inanmıyorum. Çözümün kesinlikle teknik bir çözüm olduğu hissine kapılmıyorum. İronik olarak yorum, konunun tam kalbini gösteriyor; yanlış yapılması halinde bu konuyu ele almak aşırı derecede rahatsız edici olabilir.
Nelson

49

Hangimiz doğru?

Bir zamanlar, patronun öyleydi. Fakat zaman geçtikçe işler değişiyor. Bugünlerde sizsiniz (ama patronunuza koşmadan önce Nelson'ın cevabını da mutlaka okuyun ).

MySQL'in eski sürümleri ve çoğunlukla her şeyin eski sürümleri , eski Latince1 / ISO-8859-1 (5) ile UTF8'den çok daha iyi çalıştı.

UTF8'in çoğunlukla her yerde yaratılmasının, gelişmesinin ve ittirilmesinin bir nedeni var: eğer uygun şekilde uygulanırsa, çok daha iyi çalışır . Latin1 karakterinin 8 bit olması, UTF8 karakterinin 8 ile 32 bit uzunluğunda olması nedeniyle ortaya çıkan bazı performans ve depolama sorunları vardır. Bu yüzden planlama yaparken VARCHARbunu göz önünde bulundurmanız gerekir. Ve arama rutinleriniz biraz daha yavaş olacak. Onlar (örn aramalar fazla şeyler yapmak mümkün olacak vurgu duyarlılığı veya olmadan geniş bir çalışma olmadan Latin1 olanlar yapamaz.), Ancak bunlar olacak biraz daha fazla zaman alır.

Ancak, diğer yandan, depolama ucuz , dosya boyutlarındaki gerçekçi ek maliyet% 2-3'ten az, hesaplama gücü de ucuz ve Moore Yasası ile daha ucuz hale geliyor; ise zaman ve müşterilerinizin beklentileri kesinlikle değildir .

Bu tür araçlar geliştiren siz olsaydınız, arama araçları vb. İçin endişelenmeniz gerekebilir . Ama sen muhtemelen değilsin. Sen kullanmak bu araçları; Dün tamamen UTF8 uyumlu olmayanlar bile (önceki MySQL'lerin olmadığı gibi), bugün ya da yakında olacak (örneğin utf8mb4 destekli MySQL).

Yani dikkatlice (planlama ve UTF8 doğru yolu uygulayarak değil çok makul bir koduna sahip olabilir sonradan olarak Latin1 ters tokat) geleceğe dönük , Hiç Asya ülke ile iş yapan planlıyorsanız, bir çok iyi olduğunu Şey. Ve böyle bir planınız yoksa, başkalarının sahip olacağı ve bu insanların sizin müşterileriniz, tedarikçileriniz veya ortaklarınız olabilir.

Bu yüzden size UTF8 verilerini göndermeye başladıklarında, Latin1'e dönüştürmek ve bunları dönüştürmek için karmaşık bir şey ayarlamanız ve çözülemez durumlarla ilgilenmeniz gerekir.

Bütçeyi hesaba kattığınızda , birkaç kötülüğün kötü mojibake ninjalarına karşı maliyeti göz önünde bulundurulur ve onların gitmeyeceklerini düşünün - zaten keşfettiğiniz gibi - o zaman UTF8'e gitmenin sadece daha basit olmadığını fark edersiniz, de daha ucuz .


4

Karakteri yalnızca ASCII ile sınırlandırmanın mantıklı olabileceği bazı durumlar sınırlı seçim alanları içindir, örneğin durum alanları; alfanümerik karakterlerden ve birkaç sembolden başka her şeye sahip olmaları.

Diğer metinler için UTF-8 kullanın.


2
MySQL'in numaralandırması yok mu?
raptortech97

2
Ve ASCII bir UTF8 alt kümesi olduğundan, o zaman bile UTF8 kullanın.
RemcoGerlich

@RemcoGerlich: UTF8'i onlar için kullanabileceğini kabul etmiyorum. Benim görüşüme göre, dış referanslar metin değil, baytların opak dizisidir. Noter rahatlığı dışında karakter seti yoktur. Bayt dizisinin belirli karakter kümelerinde bir yorumu varsa, bu, veritabanının değil, dış sistemin veya uygulamanın etki alanıdır.
Yalan Ryan

3
@LieRyan: Bu noktayı görüyorum ama o zaman ASCII de olmamalı, muhtemelen bir ikili blob formatı ya da öylesine.
RemcoGerlich

3

Yanıtla başlamak için, sunucunuzun nasıl yapılandırıldığı önemli değildir . MySQL'deki karakter kodlaması sütun başına yapılandırılabilir (aynı tablonun karakterleri birden fazla kodlamada tutabileceği, kolay olduğu anlamına gelir). Başka bir deyişle, sunucum (ve içindeki bazı eski veritabanları), cp1251 için varsayılan olarak bağlantı üzerine doğru harmanlama ayarlayamayan (farklı donanım istemcileri) eski istemciler için (farklı donanım istemcileri) yapılandırılmış, ancak üretimdeki ana veritabanlarının tümü UTF-8 kullanıyor.

"Boş alan" derken, önemli verileri gerçekçi olarak israf olarak adlandıramazsınız, değil mi? Bununla birlikte, depolama alanı artışı, verilerinizin bulunduğu dile bağlı olarak farklı olacaktır. Sitenizin öncelikle İngilizce olması durumunda ve ASCII aralığının dışındaki karakterleri kullanarak posta kullanıyorsanız,% 100'e kadar önemsizden (% 1'den az) artacaktır. . Ve daha da fazlası, doğuya doğru ilerlerseniz. Daha sonra UTF-8 (UTF8mb4 olarak adlandırılır) özellikleri, kod noktası başına 4 bayta kadar izin verir.

Ve “kim haklı” için… Gerçek şu ki, bu teknik olmaktan çok sosyal bir sorudur. Belirli sunucu kurulumları için geçerli nedenler olabilir, ancak sonuçları bilmeniz gerekir. Ama bana sorarsanız, UTF-8'i kullanmamak için hiçbir sebep yok. Dünyadaki tüm metinleri yöneten tek tür.


MySQL, verileri sütun kodlamasına dönüştürmeden önce Veritabanı kodlamada dönüştürmeye çalışır. Utf8 istemcisi, latin1 veritabanı ve utf8 columnt varsa, o zaman metin verileri kaybolabilir.
Ivan Solntsev

Ivan, bu tamamen farklı bir soru. Karakter kümesi istemcisi, karakter kümesi sunucusu, karakter kümesi bağlantısı, karakter kümesi sonuçları arasındaki ilişki MySQL belgelerinde uzun bir yazıdır. Sütun başına harmanlama ayarları durumunda, "veritabanı harmanlaması" sütun harmanlamasıdır ve veritabanı harmanlamasını yok sayarak doğrudan karakter kümesi sonucuna dönüştürülür.
AnrDaemon

0

Ona web trafiği için UTF-8'in varsayılan olduğunu açıkla. Ve herhangi bir kullanıcı, tarayıcılarına herhangi bir geçerli unicode karakter girebilir.

Utf-8 / unicode'u önden arkaya sonuna kadar taşımak, utf-8-> latin-1-> utf-8'den kaynaklanan çok sayıda ve çeşitli konularla uğraşmaktan çok daha kolaydır.

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.