Sollte Latin-1 über UTF-8 verwendet werden, wenn es um die Datenbankkonfiguration geht?

65

Wir verwenden MySQL in der Firma, für die ich arbeite, und wir erstellen sowohl clientseitige als auch interne Anwendungen mit Ruby on Rails.

Als ich hier anfing zu arbeiten, stieß ich auf ein Problem, auf das ich noch nie gestoßen war. Die Datenbank auf dem Produktionsserver ist auf Latin-1 eingestellt, was bedeutet, dass das MySQL-Gem eine Ausnahme auslöst, wenn Benutzereingaben vorhanden sind, bei denen der Benutzer UTF-8-Zeichen kopiert und einfügt.

Mein Chef nennt diese "schlechten Zeichen", da die meisten von ihnen nicht druckbare Zeichen sind, und sagt, dass wir sie entfernen müssen. Ich habe ein paar Wege gefunden, um dies zu tun, aber irgendwann sind wir in einem Umstand gelandet, in dem ein UTF-8-Zeichen benötigt wurde. Außerdem ist es etwas umständlich, zumal es die einzige Lösung zu sein scheint, über die ich jemals gelesen habe, die Datenbank auf UTF-8 zu setzen (für mich sinnvoll).

Das einzige Argument, das ich gehört habe, um bei Latin-1 zu bleiben, ist, dass das Zulassen von nicht druckbaren UTF-8-Zeichen die Text- / Volltextsuche in MySQL durcheinander bringen kann. Ist das wirklich wahr?

Gibt es andere Gründe, warum man Latin-1 anstelle von UTF-8 verwenden sollte? Ich verstehe, dass es überlegen und allgegenwärtiger wird.

Ravenstine
quelle
4
@jon LATIN-1 ist nicht englischspezifisch. Spanisch ist dort perfekt enthalten, ebenso wie Französisch, wenn ich mich nicht irre.
Darkhogg
4
@Darkhog: Latin1 ist zwar nicht spezifisch für Englisch, beschränkt sich aber im Wesentlichen auf westeuropäische Alphabete.
Bart van Ingen Schenau
16
Der einzige mögliche Vorteil der Verwendung von Latin 1 anstelle von UTF-8 in einem modernen System ist Sabotage. Dies ist natürlich nur ein Vorteil für den Saboteur und für alle seine Loyalitäten, nicht für die Eigentümer oder Entwickler des Systems.
Jon Hanna
13
Schade, dass Ihre Datenbank nicht in der Lage ist, das Euro-Symbol oder sogar meinen Namen (דותן) zu speichern.
Dotancohen
20
Benutzer "Kopieren und Einfügen" von Nicht-Latein-1-Zeichen? Behandle Unicode nicht als irrelevantes, leichtfertiges Ding, das nur boshaften Nerds etwas bedeutet. ziemlich viel von uns geben Zeichen , die nicht in Latin-1 auf einer regelmäßigen Basis passen - ich höre eine Menge Leute sprechen nicht-europäischen Sprachen, auch ♥
Eevee

Antworten:

131

Unicode ist sicherlich schwierig, und die UTF-8-Codierung weist einige unbequeme Eigenschaften auf. UTF-8 ist jedoch zum De-facto-Standard im Web geworden und übertrifft ASCII, Latin-1, UCS-2 und UTF-16. Verwenden Sie UTF-8 einfach überall .

Der wichtigste Grund, warum Sie Unicode unterstützen sollten, ist, dass Sie keine unnötigen Annahmen über Benutzereingaben treffen sollten. Ich habe keine Ahnung, was Ihre Domain ist, aber Dinge wie hebräische Benutzernamen, ein Blog-Post über China, ein Kommentar mit Emoji oder einfach gut gestalteter Text - wie „dies“ - sollten möglich sein ... Oh, das waren typografisch korrekte Anführungszeichen ( “”Anstelle von "") werden breite Bindestriche und Auslassungspunkte angezeigt. Dies sind Zeichen, die im englischen Text üblich sind, aber von ASCII oder Latin-1 nicht unterstützt werden. Andere Skripte nicht zu unterstützen, ist also nicht nur ein großes Problem für andere Kulturen, aber wenn Sie sich an Latin-1 halten, können Sie nicht einmal richtig Englisch schreiben.

Die Vorstellung, dass Unicode nur "schlechte Zeichen" zulässt, ist falsch. Ja, Text ist wirklich kompliziert und Unicode wird das nicht vor Ihnen verbergen. Ihr Chef denkt möglicherweise über zusammengesetzte Zeichen nach, bei denen ein Basiscodepunkt wie adurch nachfolgende Codepunkte geändert wird, die z. B. diakritische Zeichen darstellen, um ein visuelles Zeichen wie z á. Dies stört Sie nicht wirklich, wenn Sie versuchen, eine Suche durchzuführen, wenn Sie eine Art Normalisierung durchführen. Sie können beispielsweise den gesamten Text in der NFC-Form speichern, wodurch solche Kompositionen in ihre vorkompositionierte Form gebracht werden, sofern eine verfügbar ist. Bei der Suche können Sie auch alle zusammensetzenden Zeichen aus dem Text entfernen, was jedoch in einigen Sprachen zu einer wesentlichen Änderung der Bedeutung führen kann.

Unicode fügt auch viele nicht druckbare Zeichen hinzu - aber auch ASCII hat jede Menge davon. Wirst du eine NUL in der Mitte einer Zeichenfolge behandeln? Wie wäre es mit 0x1C, einem "File Separator"? Ich habe noch nie die Hälfte davon gesehen . Latin-1 fügt einen weichen Bindestrich hinzu, der auf die Möglichkeit von Wortumbrüchen hinweist, ansonsten jedoch unsichtbar ist. Bricht das auch Ihre Volltextsuche? Mit anderen Worten, sogar mit ASCII und Latin-1 können Sie Ihre Eingabe vollständig unterbrechen, wenn Sie davon ausgehen, dass es sich nur um druckbaren Text handelt!

amon
quelle
8
Aus Datenbanksicht sind / sollten einige dieser Zeichen in einem Textfeld (text / varchar / char / etc.) Nicht zulässig sein. MySQL hat Null - Zeichen in diesen Datentypen erlauben, aber auch andere Datenbanken wie PostgreSQL nicht. Sie sollten BLOB (MySQL) oder BYTEA (PostgreSQL) verwenden, wenn Sie solche Zeichen speichern möchten.
Cimmanon
15
"Wenn Sie sich an Latin-1 halten, können Sie nicht einmal richtig Englisch schreiben" Das ist gut, sonst würde Unicode noch stärker widerstehen. ;-)
Deduplizierer
3
@ PaŭloEbermann Eingebettete NUL-Zeichen bedeuten, dass Ihre Daten ein binärer Blob und nicht nur eine Zeichenfolge sind. NULs waren ein seltsames Beispiel, da ich glaube, dass UTF-8 die Verwendung eines \0Bytes als Teil einer Multibyte-Codierung vermeidet , um sicherzustellen, dass nicht UTF8-fähiger Code nicht in der Mitte einer Zeichenfolge stoppt.
Peter Cordes
7
Alle Unicode-Zeichen sind druckbar - Sie brauchen nur die richtige Schriftart :-)
James Anderson
4
@JamesAnderson die Schrift wäre dann falsch und kaputt. en.wikipedia.org/wiki/Unicode_control_characters
djechlin
62

Ich denke, über die technische Frage hinaus hat Ihr Chef möglicherweise nicht die Zeit, sich über die aktuellen Standards auf dem Laufenden zu halten.

Da seine Haltung zum Mittagessen nicht völlig veraltet ist, respektieren Sie seine Position bei der Erörterung dieser Angelegenheit (und Sie müssen sich daran erinnern, zu diskutieren , nicht zu streiten) und versuchen Sie, Bedenken in Bezug auf UTF-8 auszuräumen. Ich vermute, dass das zugrunde liegende Problem kein technisches Problem ist und möglicherweise ein gewisses Maß an Verhandlungsgeschick erfordert.

Nelson
quelle
6
Ich konnte nicht mehr genehmigen. Tatsächlich bedaure ich, dass ich in meiner eigenen Antwort die "menschliche Seite" völlig übersehen habe, die in dieser Ausgabe möglicherweise von größter Bedeutung ist. Ich wünschte, ich könnte mehr als einmal
upvoten
2
alles ausserhalb von latin-1 anrufen bad characterund denken das sind non-printablewas just out-datedfür dich?
njzk2
2
Das eigentliche Problem ist: "Handelt es sich um ein technisches Problem, mit dem wir uns befassen?" Ich glaube nicht, dass der OP-Chef zur Schule gegangen ist und dies gelernt hat, oder dass er ein technisches Handbuch / Tagebuch gelesen hat und zu diesem Schluss gekommen ist. Ich verstehe nicht, dass es sich bei der Lösung ausschließlich um eine technische Lösung handelt. Ironischerweise zeigt der Kommentar genau den Kern des Problems; Die Behebung dieses Problems kann äußerst anstößig sein, wenn dies nicht ordnungsgemäß erfolgt.
Nelson
49

Welcher von uns hat Recht?

Es war einmal Ihr Chef. Aber mit der Zeit ändern sich die Dinge. Heutzutage bist du es (aber bevor du zu deinem Chef rennst, solltest du auch Nelsons Antwort lesen ).

Alte Versionen von MySQL und alte Versionen von fast allem haben sich mit dem älteren Latin1 / ISO-8859-1 (5) besser zurechtgefunden als UTF8.

Es gibt einen Grund, warum UTF8 fast überall erstellt, weiterentwickelt und gepusht wurde: Wenn es richtig implementiert wird, funktioniert es viel besser . Es gibt einige Leistungs- und Speicherprobleme, die sich aus der Tatsache ergeben, dass ein Latin1-Zeichen 8 Bit lang ist, während ein UTF8-Zeichen 8 bis 32 Bit lang sein kann. Wenn VARCHARSie planen , müssen Sie dies berücksichtigen. Und Ihre Suchroutinen werden ein bisschen langsamer sein. Sie werden in der Lage , mehr Dinge zu tun (zB Suche mit Akzent Empfindlichkeit oder ohne . Kann nicht die in Latin1 ohne umfangreiche Arbeit tun), aber sie werden ein bisschen mehr Zeit in Anspruch nehmen.

Auf der anderen Seite ist Speicher billig , der realistische Overhead bei Dateigrößen liegt unter 2-3%, die Rechenleistung ist auch billig und wird gemäß Moores Gesetz billiger. während Ihrer Zeit und Erwartungen Ihrer Kunden auf jeden Fall nicht .

Sie könnten für Suchmaschinen kümmern, usw. , wenn Sie derjenige sind zu entwickeln solche Werkzeuge. Aber Sie sind wahrscheinlich nicht. Sie benutzen diese Werkzeuge; Sogar diejenigen, die gestern nicht vollständig UTF8-konform waren (wie die früheren MySQLs nicht), sind heute oder in Kürze (z. B. MySQL mit utf8mb4-Unterstützung).

Wenn Sie UTF8 also sorgfältig planen und implementieren (und nicht nachträglich auf Latin1 setzen), erhalten Sie einen Code, der sehr zukunftssicher ist. Wenn Sie also jemals mit einem asiatischen Land Geschäfte tätigen möchten , ist dies eine sehr gute Sache Ding. Und wenn Sie keine solchen Pläne haben, werden andere Leute diese haben, und diese Leute könnten Ihre Kunden, Lieferanten oder Partner sein.

Wenn sie Ihnen UTF8-Daten senden, müssen Sie ein kompliziertes Ding einrichten, um Latin1 hin und her zu konvertieren und unlösbare Fälle zu behandeln.

Wenn Sie das Budget einkalkulieren und die Kosten für mehrere Scharmützel gegen die bösen Mojibake-Ninjas in Betracht ziehen und bedenken, dass sie nicht verschwinden werden - wie Sie bereits festgestellt haben -, werden Sie feststellen, dass UTF8 nicht nur einfacher, sondern auch einfacher ist auch billiger .

LSerni
quelle
4

In einigen Situationen kann es sinnvoll sein, den Zeichensatz nur auf ASCII zu beschränken, wenn nur begrenzte Auswahlfelder zur Verfügung stehen, z. B. Statusfelder, da Sie die möglichen Werte streng kontrollieren und Fremdschlüssel / Verweise auf ein externes System, da selten Gründe dafür vorliegen Sie dürfen nur alphanumerische Zeichen und ein paar Symbole enthalten.

Verwenden Sie für alle anderen Texte einfach UTF-8.

Lüge Ryan
quelle
2
Hat MySQL keine Aufzählungen?
Raptortech97
2
Und da ASCII eine Teilmenge von UTF8 ist, verwenden Sie UTF8 auch dann.
RemcoGerlich
@RemcoGerlich: Ich bin nicht einverstanden, dass Sie UTF8 für diese verwenden könnten. Aus meiner Sicht sind externe Referenzen kein Text, sondern eine undurchsichtige Folge von Bytes. Sie haben keinen Zeichensatz, außer zur Vereinfachung der Notation. Wenn die Folge von Bytes in einem bestimmten Zeichensatz interpretiert wird, ist dies entweder die Domäne des externen Systems oder der Anwendung, nicht die der Datenbank.
Lie Ryan
3
@LieRyan: Ich verstehe das, aber dann sollte es auch nicht ASCII sein, wahrscheinlich irgendein binäres Blob-Format oder so.
RemcoGerlich
3

Zunächst spielt es keine Rolle, wie Ihr Server konfiguriert ist. Die Zeichenkodierung in MySQL kann spaltenweise konfiguriert werden (dh dieselbe Tabelle kann Zeichen in mehreren Kodierungen enthalten, einfach). Das heißt, mein Server (und eine Reihe älterer Datenbanken darin) ist standardmäßig für cp1251 für alte Clients konfiguriert, die beim Herstellen einer Verbindung keine korrekte Sortierung festlegen können (verschiedene Hardware-Clients), die Hauptdatenbanken in der Produktion verwenden jedoch alle UTF-8.

Apropos "Platzverschwendung" - Sie können wichtige Daten nicht realistisch als Verschwendung bezeichnen, oder? Die Erhöhung des Speicherplatzes hängt jedoch von der Sprache ab, in der sich Ihre Daten befinden. Von einer geringfügigen Erhöhung (weniger als 1%), wenn Ihre Site hauptsächlich in englischer Sprache vorliegt, bis zu 100%, wenn Mailny-Zeichen außerhalb des ASCII-Bereichs verwendet werden . Und noch mehr, wenn Sie weiter nach Osten ziehen. Spätere UTF-8-Spezifikationen (sog. UTF8mb4) erlauben bis zu 4 Bytes pro Codepunkt.

Und um "wer hat Recht" ... Die Wahrheit ist, dies ist mehr eine soziale als eine technische Frage. Es kann gültige Gründe für bestimmte Serverkonfigurationen geben, aber Sie müssen die Auswirkungen kennen. Aber wenn Sie mich fragen, gibt es keinen Grund, UTF-8 nicht zu verwenden. Es ist die einzige Art, die alle Texte der Welt regiert.

AnrDaemon
quelle
MySQL versucht, Daten in der Datenbankcodierung zu konvertieren, bevor sie in die Spaltencodierung konvertiert werden. Wenn Sie einen utf8-Client, eine latin1-Datenbank und eine utf8-Spalte haben, können Textdaten verloren gehen.
Ivan Solntsev
Ivan, das ist eine ganz andere Frage. Die Wechselwirkung zwischen Zeichensatz-Client, Zeichensatz-Server, Zeichensatz-Verbindung und Zeichensatz-Ergebnissen ist ein langer Artikel in der MySQL-Dokumentation. Bei spaltenbezogenen Sortierungseinstellungen ist "Datenbanksortierung" eine Spaltensortierung, die direkt in ein Zeichensatzergebnis konvertiert wird, wobei die Datenbanksortierung ignoriert wird.
AnrDaemon
0

Erklären Sie ihm einfach, dass UTF-8 die Standardeinstellung für den Webdatenverkehr ist. Jeder Benutzer kann ein gültiges Unicode-Zeichen in seinen Browser eingeben.

Es ist einfach viel einfacher, utf-8 / unicode vom Anfang bis zum Ende zu haben, als sich mit den vielen und verschiedenen Problemen zu befassen, die sich aus utf-8-> latin-1-> utf-8 ergeben.

James Anderson
quelle