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


65

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

ここで働き始めたとき、私は今まで遭遇したことのない問題に遭遇しました。実稼働サーバー上のデータベースはLatin-1に設定されます。これは、ユーザーがUTF-8文字をコピーして貼り付けるユーザー入力があるたびに、MySQL gemが例外をスローすることを意味します。

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

Latin-1に固執することについて聞いた唯一の議論は、印刷できないUTF-8文字を許可すると、MySQLでテキスト/フルテキスト検索が台無しになる可能性があるということです。これは本当ですか?

UTF-8ではなくLatin-1を使用する他の理由はありますか?それが優れており、よりユビキタスになることは私の理解です。


4
@jon LATIN-1は英語固有ではありません。スペイン語は完全に含まれていますが、私が間違っていなければフランス語も含まれています。
ダークホッグ

4
@Darkhog:Latin1は確かに英語専用ではありませんが、基本的に西ヨーロッパのアルファベットに制限されています。
バートヴァンインゲンシェナウ

16
最新のシステムでUTF-8ではなくLatin 1を使用することで得られる唯一の利点は、妨害行為です。もちろん、それは破壊工作者にとっての利益であり、システムの所有者や開発者にとってではなく、彼らの忠誠心が誰であってもです。
ジョンハンナ

13
データベースがユーロ記号や私の名前(דותן)さえも保持できないのは残念です。
-dotancohen

20
ユーザーは非ラテン1文字を「コピーして貼り付け」ますか?ユニコードを、いたずら好きのオタクだけが気にする無関係な軽薄なものとして扱わないでください。私たちの多くは、定期的にラテン1に収まらない文字を入力します。多くの人が非ヨーロッパ言語を話すと聞きます。♥
Eevee

回答:


131

ユニコードは確かに難しく、UTF-8エンコーディングにはいくつかの不便な特性があります。ただし、UTF-8は、ASCII、Latin-1、UCS-2、UTF-16を超えて、Webの事実上の標準エンコーディングになりました。ただ、どこでもUTF-8を使用します

Unicodeをサポートする最も重要な理由は、ユーザー入力について不必要な仮定をしてはいけないということです。あなたのドメインが何であるかはわかりませんが、ヘブライ語のユーザー名、中国に関するブログ投稿、絵文字でのコメント、または「this」のような単純なスタイルのテキストは可能です。“”いうよりも"")、アン・ワイドダッシュ、省略記号、英語のテキストに共通しているが、ASCIIまたはLatin-1のによってサポートされていない文字です。そのため、他のスクリプトをサポートしないことは、他の文化に大きな関心を寄せるだけでなく、Latin-1に固執するだけでは適切な英語を書くことさえできません。

Unicodeは「悪い文字」しか許可しないという概念は間違っています。はい、テキストは本当に複雑で、Unicodeはそれをあなたから隠しません。上司は合成文字について考えている可能性があります。1つの基本コードaポイントは、たとえば発音区別符を表す後続のコードポイントによって変更され、1つの視覚文字を形成しáます。何らかの正規化を行うと、検索を実行しようとするときにこれは実際には邪魔になりません。たとえば、すべてのテキストをNFCフォームに保存すると、そのような構成が事前に構成された形式に折りたたまれます(使用可能な場合)。検索を行うときに、テキストからすべての構成文字を削除することもできますが、これにより、一部の言語では意味が大幅に変わる場合があります。

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


8
データベースの観点から、これらの文字の一部はテキストタイプフィールド(text / varchar / char / etc。)で許可されていません/許可されていません。MySQL これらのデータ型でNULL文字を許可しますが、PostgreSQLなどの他のデータベース許可しません。そのような文字を格納できるようにしたい場合は、BLOB(MySQL)またはBYTEA(PostgreSQL)を使用することになっています。
シマノン

15
「Latin-1にこだわるのは適切な英語を書くことすらできません。」それは良いことです。;-)

3
@PaŭloEbermann埋め込みNUL文字は、データが単なる文字列ではなく、バイナリBLOBであることを意味します。UTF-8は\0マルチバイトエンコーディングの一部としてバイトを使用することを避け、UTF8非対応のコードが文字列の途中で止まらないようにするため、NULは奇妙な例です。
ピーターコーデス

7
すべてのUnicode文字は印刷可能です。正しいフォントが必要です:
ジェームスアンダーソン

4
@JamesAndersonの場合、フォントは間違っていて壊れています。en.wikipedia.org/wiki/Unicode_control_characters
djechlin

62

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

彼のスタンスは完全に昼食ではなく、時代遅れであるため、この問題について議論するときは彼の立場を尊重し(議論するのではなく、議論することを忘れないでください)、UTF-8に関して彼が抱いている懸念を解決しようとします。根本的な問題は技術的な問題ではなく、ある程度のソフトスキルネゴシエーションが必要になると思います。


6
私はこれ以上承認できませんでした。実際、私は自分の答えで「人間の側面」を完全に見落としていたことを後悔しています。複数回
賛成

2
ラテン-1の外のすべてを呼び出すbad characterと、これらは思考することはnon-printableありjust out-datedますか?
njzk2

2
本当の問題は、「私たちが対処している技術的な問題ですか?」です。OPの上司が学校に行ってこれを教えたり、技術マニュアル/ジャーナルを読んでその結論に達したとは思わない。ソリューションが厳密に技術的なソリューションであるという感覚が得られません。皮肉なことに、コメントは問題の核心を正確に示しています。不適切に行うと、この問題に対処することは非常に不快になります。
ネルソン

49

私たちのどちらが正しいですか?

むかしむかし、あなたの上司はそうでした。しかし、時間が経つにつれて、状況は変わります。今日、あなたはそうです(しかし、上司に走る前に、ネルソンの答えも読んでください)。

古いバージョンのMySQL、およびほとんどすべての古いバージョンは、UTF8よりも古いLatin1 / ISO-8859-1(5)をはるかにうまく処理しました。

UTF8が作成され、進化し、ほぼすべての場所にプッシュされた理由があります。適切に実装されていれば、はるかに良く機能します。Latin1文字は8ビットですが、UTF8文字は8〜32ビット長であるという事実に起因するパフォーマンスとストレージの問題がいくつかあります。そのため、計画VARCHARする際にはこれを考慮する必要があります。そして、あなたの検索ルーチンは少し遅くなります。彼らはより多くのことをすることができます(例えば、アクセントを区別して検索するか、検索しません。Latin1での検索は大仕事なしではできません)が、少し時間かかります。

しかし、一方で、ストレージは安価であり、ファイルサイズの現実的なオーバーヘッドは2〜3%未満であり、計算能力も安価であり、ムーアの法則に従って安価になっています。一方で、あなたの時間あなたの顧客の期待は間違いありません

あなたがそのようなツールを開発するのであれば、検索ツールなどを心配する必要があるかもしれません。しかし、あなたはおそらくそうではありません。あなたは使うこれらのツールを。昨日(以前のMySQLがそうではなかったように)完全にUTF8に準拠していなかったものも、今日、または間もなく(たとえば、utf8mb4をサポートするMySQL)になります。

したがって、UTF8を慎重に計画し、正しい方法で実装することで(後付けとしてLatin1に平手打ちしないで)、非常に合理的に将来性のあるコードを手に入れることができます。もの。そして、あなたがそのような計画を持たない場合、他の人々が持っているでしょう、そしてそれらの人々はあなたの顧客、サプライヤー、またはパートナーになることができます。

したがって、彼らがUTF8データの送信を開始するとき、Latin1との間で相互に変換するために複雑な事を設定し、解決できないケースに対処する必要があります。

邪悪なもじ焼き忍者に対するいくつかの小競り合いの予算を考慮に入れて、彼らが消えないことを考えてください-あなたがすでに発見したように-あなたはUTF8を行くことがより簡単であるだけでなく、安い


4

ASCIIのみに文字セットを制限することが理にかなっている状況は、選択可能なフィールドが限られている場合です。たとえば、ステータスフィールドは、そこにある値を厳密に制御するためですそれらは英数字といくつかの記号以外のものを持っています。

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


2
MySQLには列挙型がありませんか?
raptortech97

2
また、ASCIIはUTF8のサブセットなので、その場合でもUTF8を使用してください。
RemcoGerlich

@RemcoGerlich:それらにUTF8を使用できることに同意しません。私の見解では、外部参照はテキストではなく、バイトの不透明なシーケンスです。表記上の利便性を除いて、文字セットはありません。バイトシーケンスが特定の文字セットで解釈されている場合、それはデータベースではなく外部システムまたはアプリケーションのドメインのいずれかです。
ライライアン

3
@LieRyan:その点はわかりましたが、ASCIIでもないはずです。おそらく、バイナリBLOB形式などです。
RemcoGerlich

3

答えから始めるために、サーバーがどのように構成されているかは重要ではありません。MySQLの文字エンコードは、列ごとに構成できます(つまり、同じテーブルに複数のエンコードの文字を簡単に保持できます)。つまり、サーバー(およびその中の多数のレガシーデータベース)は、接続時に正しい照合を設定できない古いクライアント(異なるハードウェアクライアント)に対してデフォルトでcp1251用に構成されていますが、運用環境のメインデータベースはすべてUTF-8を使用しています。

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

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


MySQLは、データを列エンコードに変換する前に、データベースエンコードで変換しようとします。utf8クライアント、latin1データベース、utf8 columntがある場合、テキストデータが失われる可能性があります。
イヴァンソルンツェフ

イヴァン、それはまったく別の質問です。character-set-client、character-set-server、character-set-connection、character-set-results間の相互作用は、MySQLドキュメントの長い記事です。また、列ごとの照合設定の場合、「データベース照合」は列照合であり、データベース照合を無視して文字セット結果に直接変換されます。
-AnrDaemon

0

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

utf-8-> latin-1-> utf-8に起因する多くのさまざまな問題に対処するよりも、フロントエンドからバックエンドまでずっとutf-8 / unicodeを使用する方がはるかに簡単です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.