データベース構成に関しては、Latin-1をUTF-8よりも使用する必要がありますか?

私は仕事をしている会社でMySQLを使用しており、Ruby on Railsを使用してクライアント向けアプリケーションと社内アプリケーションの両方を構築しています。

When I started working here, I ran into a problem what I had never encountered before; the database on the production server is set to Latin-1, meaning that the MySQL gem throws an exception whenever there is user input where the user copies & pastes UTF-8 characters.

私の上司はこれらの「悪い文字」と呼んでいます。それらのほとんどは印刷できない文字なので、それらを取り除く必要があると言っています。これを実行する方法をいくつか見つけましたが、結局はUTF-8文字が必要な状況に陥りました。さらに、この問題について私がこれまでに読んだ唯一の解決策は、データベースをUTF-8に設定することだけであるように思われるので、これは少し面倒です。

Latin-1にこだわることについて私が聞いたことのある唯一の議論は、印刷不可能なUTF-8文字を許可するとMySQLのテキスト/フルテキスト検索がめちゃくちゃになることがあるということです。これは本当に本当ですか?

UTF-8よりもLatin-1を使用すべき他の理由はありますか?私はそれが優れていること、そしてより普遍的になることを理解しています。

62
彼はあなたの上司です。ただそれが彼の決断だということを人々に理解させてください。
追加された 著者 Ionuț G. Stan,
最新のシステムでUTF-8ではなくLatin 1を使用することによる唯一の可能性のある利点は、妨害行為です。もちろん、それは破壊工作員にとっての恩恵であり、彼らの忠誠心が誰であるかに関係なく、システムの所有者や開発者にとってではありません。
追加された 著者 justinbach,
Latin-1は文字セット、UTF-8は文字エンコーディングです。両者を比較しても意味がありません。これらはまったく異なるものです。 UTF-8は、実際にはLatin-1の有効なエンコーディングです。
追加された 著者 Lawrence B. Crowell,
@Darkhog:Latin1は確かに英語に固有のものではありませんが、それは本質的に西ヨーロッパのアルファベットに限られています。
追加された 著者 Dee,
@ CortAmmon:感情的ではありません。しかし、これらのことはすでに生産段階にあります。したがって、古いシステムを変換する必要があるため、ゼロ以外の財務コストがあります。 DB上だけでなく、DBに関わるすべての古いコード。
追加された 著者 Martin York,
UTF-8に変換すると、どれだけのコードベースが壊れるのでしょうか。
追加された 著者 xirt,
@jon LATIN-1は 英語固有ではありません。私が間違っていなければ、スペイン語もフランス語にも完璧に含まれています。
追加された 著者 Vincent Peres,
Latinがデフォルトですが、UTF-8(Unicode)では、中国語、キリル文字などのように任意の文字を格納できます。Latin1はASCIIの拡張であり、非常に限定された(英語固有の)文字セットを提供します。アプリが米国の枠を超えない場合、Latin1は問題ありませんが、私はUTF-8に移行するでしょう。
追加された 著者 Anup Chaudhary,
@Darkhogg - あなたは正しい、私のコメントは限られた文字セットとスクラッチEngligh特有を含むように修正されるべきです。それを指摘するためのTHX。
追加された 著者 Anup Chaudhary,
@Darkhoggは、ウムラウト付きの大文字のYが含まれていないため、フランス語を 含まれていません。
追加された 著者 Matt Krause,
それは西洋中心の近視のように感じます。世界の人口の少なくとも半分は、Latin-1互換ではない言語を使用しています。あなたが本当に包括的になりたいのであれば、ビジネスは大きな問題を抱えることになります。
追加された 著者 Dennis,
@ njzk2:それを教えてくれてありがとう。 MySQLにもFTSがあることがわかりました。特定の文字を無視するように見えるので、おそらく印刷不可能な制御文字も無視します(なぜ誰かがそれらを含めたいのか私にはわからないのでこれは意味があります)。
追加された 著者 Ravenstine,
@zehpuk:あなたは正しいです、UTF-8は文字セットではないからです。私の声明は理解の欠如によるものでした。
追加された 著者 Ravenstine,
この質問はデータベース管理者に適しています。
追加された 著者 Philipp,
あなたのデータベースにユーロ記号、あるいは私の名前(דותן)を入れることができないのは残念です。
追加された 著者 Jimmy,
この質問の技術的な問題と "あなたの上司"との間に何か他のものがありますか?質問をする前に、視点を無知に聞こえるようにするだけですか?
追加された 著者 djechlin,
@xehpuk UTF-8形式に従って内部的に8ビットで表現される書記素の視覚的表現?
追加された 著者 Alex,
@Ravensine:全文検索に関しては、合成文字の親和性、制御文字、大文字と小文字の区別を扱うツールがあります。 MySQLについてはわかりませんが、SQLiteにはFTSがあります。 sqlite.org/fts3.html#section_1
追加された 著者 njzk2,
@JörgWMittag:Latin-1は文字エンコーディングです。これは文字セット(Unicodeのブロック)でもありますが、これはこの問題で考慮されるものではありません
追加された 著者 njzk2,
@Darkhogg:それほどではありません。 (スペイン語はもちろん、フランス語はそれほど多くありません)
追加された 著者 njzk2,
@JörgWMittag - いいえ、MySQLの用語では、latin1とutf8の両方が文字セットです。 dev.mysql.com/doc/refman/5.5/jaを参照してください。 /charset-charsets.html おそらくMySQLの設計者による専門用語の使い方がずさんですが、明らかにこれはOPが求めていることです。
追加された 著者 ToolmakerSteve,
あなたがこれにどう近づくかに注意してください。答えは正しいですが、あなたは政治情勢を考慮しなければなりません。 5年間のコンソーシアムと無数の工数を要する国際的に認められた基準に直面したときに「悪いキャラクター」を泣く人 - それはあなたがただあなたに提供したくない人の一種です論理的な議論とそれがそれ自身のために話すと仮定する。あなたは同様に感情的な議論を築き上げるために時間をかける必要があるでしょう。
追加された 著者 Cort Ammon,
Latin-1文字セットはかなり制限されており、ヨーロッパ言語の半分もサポートしていません。ラテン語-1でPaulErdősの名前を綴ることはできません。
追加された 著者 progo,
ユーザーがラテン1以外の文字を「コピーして貼り付け」ますか。いたずら好きなオタクだけが気にかけている無関係な軽薄なものとしてUnicodeを扱わないでください。私たちの多くはラテン語-1に定期的に収まらないタイプの文字 - 私は多くの人がヨーロッパ以外の言語を話すのを聞きます。
追加された 著者 acapola,

6 答え

Unicodeは確かに困難であり、UTF-8エンコーディングにはいくつかの不都合な特性があります。ただし、UTF-8は、ASCII、Latin-1、UCS-2、およびUTF-16を超える、Web上の事実上の標準エンコーディングになりました。 いたるところでUTF-8を使用するだけです。

Unicodeをサポートする必要がある最も重要な理由は、ユーザー入力について不必要な仮定をしてはいけないということです。あなたのドメインが何であるかわかりませんが、ヘブライ語のユーザー名、中国に関するブログ投稿、絵文字でのコメント、または単に「this」のようなスタイルの良いテキストなどは可能でしょう…ああ、それらは表記上正しい引用符でした( "" )ではなく“” 、ダ​​ッシュ、および省略記号。英語のテキストでは一般的ですが、ASCIIまたはLatin-1ではサポートされていません。 。したがって、他のスクリプトをサポートしていないことは、他の国の文化にとって重要なことではありませんが、Latin-1に固執しても適切な英語を書くことさえできません。

Unicodeが「悪い文字」しか認めないという考えは間違っています。はい、テキストは本当に複雑です、そして、Unicodeはあなたからそれを隠しません。あなたの上司は、 a のような1つの基本コードポイントがその後のコードポイントによって変更されるような合成文字について考えているかもしれません。発音区別符号を表して、áのような1つの視覚的な文字を形成します。ある種の正規化をしている場合に検索しようとすると、これは実際にはうまくいきません。たとえば、すべてのテキストをNFC形式で保存して、そのようなコンポジションを作成済みの形式に折りたたむことができます(使用可能な場合)。検索時には、テキストからすべての構成文字を削除することもできますが、言語によっては意味が大きく変わる可能性があります。

Unicodeも印刷不可能な文字をたくさん追加します - しかしASCIIでもそれらの負荷があります。文字列の途中でNULを処理しますか?ファイル区切り文字の0x1Cはどうですか。 その半分を見たことがありません。 Latin-1は、単語分割の機会を示すソフトハイフンを追加しますが、それ以外は表示されません。それはあなたの全文検索も壊しますか?言い換えれば、ASCIIやLatin-1でさえも、それがすべて印刷可能なテキストであると仮定すれば、入力を完全に中断することができます。

127
追加された
@amon:UTF-8が他のUnicodeエンコーディングよりも優れている「不都合なプロパティ」について詳しく教えてください。私が知っている唯一のものは、UTF-16よりもアジアの密集したテキストのサイズがわずかに悪いだけであり、マルチコードユニットのコードポイントはUTF-32とは対照的です。そして、両方の点が完全に相殺されています。マークアップ、ソースコード、プロトコル、そして他のほとんどの言語のような、ASCIIを好む/特徴とするもののサイズが異なるため、UTF-16です。 UTF-32はそれよりはるかに大きく、そしてUnicodeはマルチコードポイント文字を持っています。
追加された 著者 Shizam,
「Latin-1にこだわっても適切な英語を書くことさえできません」それは良いことです。 ;-)
追加された 著者 Shizam,
AAA @これらは本当にASCII制御文字であり、あなたはそれらを表示するフォントを手に入れることができます - デバッグや16進エディタに非常に役に立ちます。
追加された 著者 James Anderson,
すべてのUnicode文字は印刷可能です - 正しいフォントが必要です:-)
追加された 著者 James Anderson,
@PaŭloEbermann埋め込みNUL文字は、あなたのデータが単なる文字列ではなく、バイナリBLOBであることを意味します。 UTF-8はマルチバイトエンコーディングの一部として \ 0 バイトを使うことを絶対に避けているので、NULは奇妙な例です。文字列の中央
追加された 著者 Mathieu Ravaux,
@ cimmanon BLOBは文字ではなくバイナリデータを含みますね。
追加された 著者 Paŭlo Ebermann,
@Deduplicatorさて、あなたはあなたのエンコーディングの長所と短所を知っています。 UTF-8の主な欠点は、それが可変長エンコーディングであるということです。これはほとんどの場合かなりのスペースを節約しますが、特定の操作をより困難にします。しかしMySQL + Railsのコンテキストでは、これらの詳細はすでにプログラマからは見えません。 UTF-8は他のすべてのUnicodeエンコーディング(UTF-16、UTF-32)よりも勝ちです。なぜなら、それらはより多くのメモリを浪費する傾向があり、UTF-16も可変長だからです。 MySQLのコンテキストでは、 utf8 エンコーディングはUCS-2と同じくらい壊れていてBMPのみをサポートするため、 utf8mb4 エンコーディングを選択するように注意する必要があります。
追加された 著者 amon,
@JamesAndersonフォントが間違って壊れていました。 ja.wikipedia.org/wiki/Unicode_control_characters
追加された 著者 djechlin,
データベースの観点からは、これらの文字の一部はテキストタイプフィールド(text/varchar/char /など)には使用できません。 MySQLはこれらのデータ型でnull文字を許可していますが、PostgreSQLのような他のデータベースでは許可されていません。そのような文字を格納できるようにしたい場合は、BLOB(MySQL)またはBYTEA(PostgreSQL)を使用することになっています。
追加された 著者 Zequez,

技術的な問題を超えて、あなたの上司は現在の標準を最新に保つ時間がないかもしれません。

彼の立場は昼食に完全に向けられているのではなく、時代遅れで、この問題について議論する際に彼の立場を尊重し(そして議論するのではなく議論することを忘れないでください) UTF-8に関して。根本的な問題は技術的な問題ではないと思われ、ある程度のソフトスキル交渉が必要になるかもしれません。

62
追加された
latin-1の外にあるものすべてに電話をかけて不適切な文字を印刷して印刷できないと思ったのはただ古いですか?
追加された 著者 njzk2,
本当の問題は、「それは我々が扱っている技術的な問題なのか?」です。私は、OPの上司が学校に行ってこれを教えたとか、技術マニュアルや雑誌を読んでその結論に達したとは思わない。私はその解決策が厳密には技術的な解決策であるという意味を持っていません。皮肉なことに、コメントはまさに問題の中心を示しています。不適切に行われた場合、この問題に対処することは非常に不快になる可能性があります。
追加された 著者 Nelson,
これ以上承認できませんでした。実のところ、私は自分自身の答えで「人間の側面」を完全に見逃していたことを後悔しています。私が何度も投票することができればいいのに:-)
追加された 著者 LSerni,

どちらが正しいですか?

昔々、あなたの上司はいました。しかし時間が経つにつれて、物事は変わります。今日では、あなたはそうです(しかし、あなたの上司に走る前に、 Nelsonの答えも必ず読んでください)。

古いバージョンのMySQL、および古いバージョンのほとんどすべてのものは、UTF8よりも古いLatin1/ISO-8859-1(5)の方がはるかに優れています。

UTF8が作成され、進化し、そしてほとんどどこにでもプッシュされてきたのには理由があります:適切に実装されれば、それはもっとよく動きます。 Latin1文字が8ビットであるのに対し、UTF8文字は8から32ビットの長さである可能性があるため、パフォーマンスとストレージの問題がいくつかあります。そのため、 VARCHAR を計画する際には、これを考慮する必要があります。そして、検索ルーチンは少し遅くなります。 より多くのことができるようになります(たとえば、アクセントの区別を付けて、または付けずに検索できます)。ラテン語1でそれらを大規模な作業なしで行いますが、それらはもう少し時間がかかります

しかし、その一方で、記憶容量は安価、ファイルサイズに対する現実的のオーバーヘッドは2〜3%未満、計算能力も安く、安価になっています。ムーアの法則一方、あなたの時間顧客の期待は絶対にできません

あなたがそのようなツールを開発する 場合は、検索ツールなどを心配しなければならないかもしれません。しかし、あなたはおそらくそうではありません。あなたはそれらのツールを使用します。昨日完全にUTF8に準拠していなかったもの(初期のMySQLはそうではなかった)でさえも、今日であるか、まもなく(例えば、utf8mb4サポートのあるMySQL)。

そのため、UTF8を正しい方法で慎重に計画して実装することで(後付けとしてLatin1よりもしないしないで)、非常に合理的に将来性のあるコードを作成できます。これまでにアジアの国々と取引をすることを計画しているのはとても良いことです。そして、あなたがそのような計画を持っていなければ、他の人々が持つでしょう、そしてそれらの人々はあなたの顧客、供給業者、またはパートナーかもしれません。

ですから、彼らがあなたにUTF8データを送り始めるとき、あなたはLatin1との間で変換するために複雑なことを設定しなければなりません、そして解決できないケースを処理します。

予算を検討する際に、邪悪なモジバケ忍者に対するいくつかの小競り合いの費用を考慮し、はそうではないと考えます。すでにお話したように、UTF8を使用する方が簡単なだけでなく、より安価になることもわかります。

49
追加された

ASCIIのみに文字セットを制限することが意味をなす場合があるいくつかの状況は、限られた選択フィールドのためのものです。ステータスフィールド。存在する可能性のある値、および外部システムへの外部キー/参照を厳密に制御するためです。これらのフィールドに英数字と少数の記号以外のものが含まれる理由はほとんどありません。

他のテキストについては、UTF-8を使用してください。

4
追加された
@RemcoGerlich:私はあなたがそれらにUTF8を使用できるとは思わない。私の考えでは、外部参照はテキストではなく、不透明なバイト列です。表記上の都合以外に文字セットはありません。バイトシーケンスが特定の文字セットで解釈される場合、それはデータベースではなく、外部システムまたはアプリケーションのドメインのいずれかです。
追加された 著者 Dave,
MySQLには列挙型がありませんか?
追加された 著者 Johanna Cristine Dy,
@LieRyan:その点はわかりましたが、その場合はASCIIではないはずです。おそらくバイナリBLOB形式などでしょう。
追加された 著者 RemcoGerlich,
ASCIIはUTF8のサブセットなので、それでもUTF8を使用してください。
追加された 著者 RemcoGerlich,

答えから始めると、サーバーの設定方法は関係ありません。 MySQLの文字エンコーディングは列ごとに設定できます(つまり、同じテーブルに複数のエンコーディングの文字を入れることができ、簡単です)。すなわち接続時に正しい照合順序を設定できない古いクライアント(異なるハードウェアクライアント)では、私のサーバー(およびその中の多数のレガシーデータベース)はデフォルトでcp1251用に設定されていますが、運用中のメインデータベースはすべてUTF-8を使用します。

「無駄なスペース」といえば、重要なデータを現実的に無駄にすることはできません。ただし、データが使用されている言語によってストレージ容量の増加は異なります。サイトが主に英語の場合はわずかな増加(1%未満)から、ASCII範囲外の文字を使用する場合は100%まで増加します。 。さらに東に移動すると、さらにもっと言えます。最近のUTF-8(いわゆるUTF8mb4)仕様では、1コードポイントあたり最大4バイトまで使用できます。

そして、「誰が正しい」…というのは…真実です、これは技術的な問題よりも社会的な問題です。特定のサーバー設定には正当な理由があるかもしれませんが、その意味を知っておく必要があります。しかし、あなたが私に尋ねるなら、UTF-8を使わない理由はありません。それは世界のすべてのテキストを支配することの一種です。

3
追加された
アイヴァン、それはまったく違う質問です。 character-set-client、character-set-server、character-set-connection、character-set-resultsの間の相互作用はMySQLドキュメントの長い記事です。また、列ごとの照合設定の場合、 "データベース照合"は列照合であり、データベース照合を無視して直接文字セット結果に変換されます。
追加された 著者 Peter,
MySQLはデータを列エンコーディングに変換する前にデータベースエンコーディングに変換しようとします。 utf8クライアント、latin1データベース、utf8カラムがある場合、テキストデータが失われる可能性があります。
追加された 著者 Nick,

UTF-8がWebトラフィックのデフォルトであることを彼に説明してください。また、どのユーザーも自分のブラウザに有効なUnicode文字を入力できます。

Its just much easier to have utf-8/unicode all the way from front end to back end than to deal with the many and various issues that result from utf-8-> latin-1-> utf-8.

0
追加された