私の勤める会社ではMySQLを使用しており、Ruby on Railsを使ってクライアント向けと社内向けの両方のアプリケーションを構築しています。
本番サーバのデータベースはLatin-1に設定されており、ユーザーがUTF-8文字をコピー&ペーストするような入力があると、MySQL gemが例外をスローするのです。
私の上司は、これらの文字のほとんどが印刷不可能な文字であることから、これらを「悪い文字」と呼んでおり、これらを取り除く必要があると言っています。私はこれを実行する方法をいくつか見つけましたが、結局UTF-8文字が必要な状況に陥ってしまいました。特に、この問題に対する唯一の解決策は、データベースをUTF-8に設定することです(私には理にかなっています)。
私が聞いたことのある Latin-1 にこだわる唯一の主張は、印刷不可能な UTF-8 文字を許可すると MySQL でのテキスト/フルテキスト検索が台無しになるというものです。これは本当にそうなのでしょうか?
UTF-8よりもLatin-1を使うべき他の理由があるのでしょうか?私の理解では、Latin-1 の方が優れており、より一般的になってきています。
Unicodeは確かに難しく、UTF-8エンコーディングはいくつかの不都合な性質を持っています。しかし、UTF-8はASCII、Latin-1、UCS-2、UTF-16を凌ぐ、ウェブにおける事実上の標準エンコーディングとなっています。ただ、どこでもUTF-8を使う。
Unicodeをサポートすべき最も重要な理由は、ユーザーの入力に対して不必要な仮定をすべきでないということです'。あなたのドメインが何なのかわかりませんが、ヘブライ語のユーザー名、中国に関するブログ記事、絵文字を使ったコメント、あるいは単に「this」のようなスタイルの良いテキストは可能なはずです。あ、これはタイプグラフィック的に正しい引用符(""
ではなく""
)、en幅ダッシュ、省略記号で、これらは英語のテキストでよく使われているがASCIIやLatin-1でサポートしていない文字でしたね。つまり、他のスクリプトをサポートしないことは、他の文化に対する大きな侮辱であるだけでなく、Latin-1に固執することは、正しい英語を書くことさえ許さないのです。
Unicodeが「悪い文字」しか許さないという考え方は間違っています。そう、テキストは実に複雑であり、Unicode はそれを隠してくれません。あなたの上司は合成文字について考えているかもしれません。ここでは、a
のような1つの基本コードポイントが、例えば発音区別符号を表す後続のコードポイントによって修正され、á
のような1つの視覚的文字を形成します。これは、ある種の正規化を行えば、検索を行う際に邪魔になることはありません。たとえば、すべてのテキストをNFC形式で保存して、そのような合成文字があれば、合成前の形式に折り畳むことができます。また、検索時には、テキストから合成文字をすべて取り除くこともできますが、言語によっては意味が大きく変わってしまう可能性があります。
Unicodeは印字不可能な文字もたくさん追加していますが、ASCIIにもたくさんあります。文字列の真ん中にあるNULは扱えるでしょうか。ファイルセパレータ」の0x1Cはどうでしょう?私はその半分も見たことがありません(https://en.wikipedia.org/wiki/ASCII#ASCII_control_code_chart)。Latin-1はソフトハイフンを追加して、単語の区切りの機会を示しますが、それ以外は見えません。それも全文検索を壊してしまうのでしょうか?つまり、ASCIIやLatin-1でも、入力がすべて印刷可能なテキストであると仮定すれば、入力を完全に中断させることができるのです
技術的な質問を超えて、あなたの上司は現在の標準を維持する時間がないのかもしれませんね。
上司のスタンスは完全に時代遅れというわけではないので、この問題を議論するときは上司の立場を尊重し(議論するのではなく、議論することを忘れてはいけません)、UTF-8に関して上司が抱いている懸念を解決するように努めてみてください。 この問題の根底にあるのは技術的な問題ではなく、ある程度のソフトスキルによる交渉が必要なのではないかと私は考えています。
どちらが正しいのでしょうか?
昔々、あなたの上司はそうでした。しかし、時代が進むにつれて、状況は変わっていきます。今は、あなたがそうです(ただし、上司に駆け寄る前に、 ネルソン'の回答も必ず読んでください)。
MySQL の古いバージョン、そして ほとんどすべての 古いバージョンは、UTF8 よりも古い Latin1/ISO-8859-1(5) の方がはるかによく扱われました。
UTF8 が作成され、進化し、ほとんどすべての場所に押し出されたのには理由があります。適切に実装された場合、それは はるかによく 機能します。UTF8 の文字が 8 ビットから 32 ビットの長さであるのに対して、Latin1 の文字は 8 ビットであるという事実から、パフォーマンスとストレージの問題が生じます。ですから、VARCHAR
を計画するときには、このことを考慮する必要があります。そして、検索ルーチンは少し遅くなります。また、検索ルーチンは少し遅くなります。Can'これらはLatin1では大規模な作業なしではできません)、しかし少し*時間がかかります。
しかし一方で、ストレージは安く、ファイルサイズに関する現実的なオーバーヘッドは2~3%未満で、コンピューティングパワーも安く、ムーアの法則とうまく調和して安くなっています。
もしあなたが検索ツールなどを開発する人であれば、心配する必要があるかもしれません。しかし、あなたはおそらくそうではないでしょう。昨日まで完全な UTF8 準拠でなかったもの(初期の MySQL がそうであったように)、現在ではそうであるもの、あるいはすぐにそうなるもの(例えば utf8mb4 をサポートした MySQL)であっても、あなたはそれらのツールを 使用 しています。
ですから、慎重に計画を立て、正しい方法でUTF8を実装することで、(後付けでLatin1を上書きするのではなく)非常に合理的にfuture-proofなコードを作成することができますし、アジア諸国とビジネスをする予定があるなら、これは非常に良いことです。そして、もしあなたにそのような計画がなくても、他の人たちがあなたの顧客、供給者、あるいはパートナーになるかもしれないのです。
そのため、彼らがUTF8データを送ってくるようになると、Latin1と相互変換するための複雑なシステムを構築し、解決不可能なケースに対処しなければならなくなります。
悪のモジバケ忍者2と何度も小競り合いをする費用を予算に入れ、あなたがすでに発見したように、彼らがいなくなることはないと考えれば、UTF8化は単純であるだけでなく、安くなることに気がつくでしょう。