私が働いている会社ではMySQLを使用しており、クライアント向けアプリケーションと内部アプリケーションの両方をRuby on Railsを使用して)構築しています。
私がここで働き始めたとき、私は今までに遭遇したことがない問題に遭遇しました。本番サーバーのデータベースはLatin-1に設定されています。つまり、ユーザーがUTF-8文字をコピーして貼り付けるユーザー入力があると、MySQL gemは例外をスローします。
私の上司は、これらの多くを印刷不可能な文字であるため、これらを「不良文字」と呼び、それらを取り除く必要があると述べています。私はこれを行ういくつかの方法を見つけましたが、結局、UTF-8文字が必要な状況になりました。加えて、特にこの問題について私が今まで読んだ唯一の解決策はデータベースをUTF-8に設定することだけであるように思えるので(それは私には理にかなっています)、少し面倒です。
Latin-1に固執するために聞いた唯一の議論は、印刷不可能なUTF-8文字を許可すると、MySQLでテキスト/フルテキスト検索が台無しになる可能性があるということです。これは本当ですか?
UTF-8ではなくLatin-1を使用する必要がある他の理由はありますか?それは優れており、ユビキタス化されていると私は理解しています。
Unicodeは確かに困難であり、UTF-8エンコーディングにはいくつかの不便な特性があります。ただし、UTF-8は、ASCII、Latin-1、UCS-2、UTF-16を凌駕する、事実上のWeb標準エンコーディングになりました。ただ どこでもUTF-8を使用 。
Unicodeをサポートする必要がある最も重要な理由は、ユーザー入力について不必要な仮定をしないことです。私はあなたのドメインが何であるかわかりませんが、ヘブライ語のユーザー名、中国に関するブログ投稿、絵文字でのコメント、または「これ」のような単純なスタイルのテキストなどが可能であるはずです…ああ、それらはタイプミス的に正しい引用符( “”
)ではなく""
、全角ダッシュ、および省略記号。英語のテキストでは一般的ですが、ASCIIまたはLatin-1ではサポートされない文字です。したがって、他のスクリプトをサポートしないことは、他の文化に単に大いに反応するだけではありませんが、Latin-1に固執すると、適切な英語を書くことさえできなくなります。
Unicodeが「不正な文字」のみを許可するという考えは間違っています。はい、テキストは本当に複雑であり、Unicodeはそれをあなたから隠しません。上司は、a
などの1つの基本コードポイントが後続のコードポイント(たとえば、区別記号を表し、á
などの1つの視覚的文字を形成します。これは、何らかの正規化を行う場合に検索を実行しようとするときに、実際には邪魔になりません。たとえば、すべてのテキストをNFCフォームに保存すると、そのようなコンポジションが使用可能な場合は、そのコンポジションが事前構成されたフォームに折りたたまれます。検索を行うときに、テキストからすべての構成文字を取り除くこともできますが、これにより、一部の言語では意味が大幅に変わる可能性があります。
Unicodeは多くの印刷不能文字も追加しますが、ASCIIでさえそれらの負荷があります。文字列の途中でNULを処理しますか? 「ファイルセパレータ」である0x1Cはどうですか?私は見たことがない それらの半分 。 Latin-1は、単語分割の機会を示すソフトハイフンを追加しますが、それ以外の場合は表示されません。それはまたあなたの全文検索を壊しますか?つまり、ASCIIとLatin-1を使用しても、すべて印刷可能なテキストであると想定すれば、入力を完全に壊すことができます。
技術的な質問を超えて、あなたの上司には現在の標準を最新の状態に保つ時間がないと思います。
彼のスタンスは完全に昼食を外すのではなく、時代遅れになっているので、この問題を議論するときは彼の立場を尊重し(そしてdiscussを忘れないでください)、彼が抱えている懸念に取り組みましょうUTF-8に関して。根本的な問題は技術的な問題ではなく、ある程度のソフトスキルネゴシエーションが必要になる可能性があります。
どっちが正しい?
むかしむかし、あなたの上司がいました。しかし、時間が経つにつれ、状況は変化します。現在、あなたはそうです(しかし、上司に出向く前にネルソンの回答も読んでください)。
MySQLの古いバージョン、およびほとんどすべての古いバージョンは、UTF8よりも古いLatin1/ISO-8859-1(5)でより適切に処理されました。
UTF8が作成され、進化し、ほとんどすべての場所にプッシュされた理由があります。適切に実装されていれば、動作しますはるかに良い。 Latin1文字が8ビットであるのに対し、UTF8文字は8〜32ビット長である可能性があるため、パフォーマンスとストレージの問題がいくつかあります。したがって、VARCHAR
を計画するときは、これを考慮する必要があります。 And検索ルーチンは少し遅くなります。彼らはより多くのことを行うことができます(たとえば、検索は アクセントの区別ありまたはなし です。Latin1で大規模な作業なしにそれらを行うことはできません)。しかしwillもう少しかかります時間。
しかし一方で、ストレージはcheap、realisticファイルサイズのオーバーヘッドは2〜3%未満であり、計算能力も安価であり、それに応じて安くなっています。ムーアの法則。 whileあなたの時間とあなたの顧客の期待は間違いなく-aren 't。
もしあなたがdevelopのようなツールであるなら、検索ツールなどについて心配する必要があるかもしれません。しかし、おそらくそうではありません。あなた使用それらのツール;昨日完全にUTF8に準拠していなかったもの(以前のMySQLはそうでなかった)でも、今日または間もなく(たとえば、utf8mb4をサポートするMySQL)です。
したがって、UTF8を適切な方法で慎重に計画および実装することにより(notLatin1に後付けすることにより)、非常に合理的なコードを作成できますfuture-proof、これは、アジアの国との取引を計画している場合、非常に良いことです。そして、あなたがそのような計画を持っていない場合、他の人々が計画し、それらの人々はあなたの顧客、サプライヤー、またはパートナーになる可能性があります。
したがって、彼らがUTF8データを送信し始めたら、Latin1との間で変換する複雑なものをセットアップし、解決できないケースに対処する必要があります。
予算を考慮に入れると、 evil mojibake ninjas に対するいくつかの小競り合いのコストを考慮し、-彼らは消えない-すでに発見したように-あなたはUTF8に移行するほうが単純であるだけでなく、cheaperにもなることがわかります。
文字セットをASCIIのみに制限することは、状況フィールドなどの限られた選択フィールドに意味がある場合があります)これは、英数字といくつかの記号以外の理由がほとんどないためです。
その他のテキストについては、UTF-8を使用してください。
答えから始めると、serverがどのように構成されているかは問題ではありません。 MySQLの文字エンコーディングは列ごとに構成できます(つまり、同じテーブルが複数のエンコーディングで文字を保持できるため、簡単です)。つまり私のサーバー(およびその中のいくつかのレガシーデータベース)は、接続時に正しい照合を設定できない古いクライアント(異なるハードウェアクライアント)に対してデフォルトでcp1251に設定されていますが、運用中のメインデータベースはすべてUTF-8を使用しています。
「無駄なスペース」と言えば、重要なデータを無駄に現実的に呼ぶことはできないでしょう?ただし、ストレージ容量の増加は、データが使用されている言語によって異なります。サイトが主に英語の場合はわずか(1%未満)から増加し、ASCII範囲。さらに、東に移動した場合。その後のUTF-8(いわゆるUTF8mb4)仕様では、コードポイントごとに最大4バイトが許可されます。
そして「誰が正しい」…真実は、これは技術的な問題というよりも社会的な問題です。特定のサーバー設定には正当な理由がある可能性がありますが、その影響を知っておく必要があります。しかし、私に尋ねれば、UTF-8を使用しない理由はありません。それは世界のすべてのテキストを支配する一種です。
UTF-8がWebトラフィックのデフォルトであることを彼に説明してください。また、ユーザーはブラウザに有効なUnicode文字を入力できます。
Utf-8-> latin-1-> utf-8に起因する多くのさまざまな問題に対処するよりも、フロントエンドからバックエンドまでutf-8/unicodeを使用する方がはるかに簡単です。