1. ホーム
  2. mysql

[解決済み] utf8_general_ciとutf8_unicode_ciの違いは何ですか?

2022-03-16 06:51:13

質問

utf8_general_ciutf8_unicode_ci 性能面での違いはありますか?

解決方法は?

2020年以降もこの問いに辿り着く人のために、より新しい選択肢として 両方 これらのうち 例えば、以下のようなものです。 utf8mb4_0900_ai_ci .

これらの照合順序はすべて、UTF-8 文字エンコーディングのためのものです。 違いは、テキストのソートと比較の方法です。

_unicode_ci_general_ci は、テキストを期待通りの方法で並べ替えたり比較したりするための、2つの異なるルールセットです。 MySQL の新しいバージョンでは、次のような新しいルールセットも導入されています。 _0900_ai_ci は、Unicode 9.0に基づく等価なルールで、等価でない _general_ci バリアントです。今これを読んでいる人は、おそらくこれらの新しい照合順序のいずれかを使うべきでしょう。 _unicode_ci または _general_ci . 以下の古い照合順序の説明は、興味本位で提供されています。

MySQL は現在、欠陥のある古い UTF-8 の実装から移行中です。 今のところ utf8mb4 の代わりに utf8 の文字エンコーディングの部分は、確実に修正されたバージョンを取得できるようにするためです。 欠陥のあるバージョンは後方互換性のために残されていますが、非推奨とされています。

主な相違点

  • utf8mb4_unicode_ci は、ユニバーサルなソートと比較のための公式のユニコード・ルールに基づいており、幅広い言語で正確にソートすることができます。

  • utf8mb4_general_ci は、速度を向上させるために多くのショートカットを取りながら、できる限りうまくやることを目的とした簡略化されたソートルールのセットです。 これは Unicode の規則には従っておらず、特定の言語や文字を使用する場合など、状況によっては望ましくない並べ替えや比較になることがあります。

    最近のサーバーでは、この性能向上はほとんど無視できる程度でしょう。 これは、サーバーのCPU性能が現在のコンピューターのごく一部であった時代に考案されたものです。

メリット utf8mb4_unicode_ci オーバー utf8mb4_general_ci

utf8mb4_unicode_ci は、ソートと比較にUnicodeのルールを使用しており、幅広い言語と幅広い特殊文字を使用する際に正しいソートを行うために、かなり複雑なアルゴリズムを採用しています。これらのルールは、言語固有の慣習を考慮する必要があります。すべての人が、私たちが「アルファベット順」と呼ぶような方法で文字をソートしているわけではありません。

ラテン語(つまりヨーロッパ言語)に関しては、ユニコードのソートと簡略化された utf8mb4_general_ci のソートには、まだいくつかの違いがあります。

  • 例えば、Unicode 照合順序は、"ß" を "ss" のように、また "Œ" を "OE" のようにこれらの文字を使う人が通常望むようにソートするのに対し、Unicode 照合順序は、? utf8mb4_general_ci は、それぞれ1文字(おそらく "s" と "e" のように)としてソートします。

  • いくつかのUnicode文字は無視可能として定義されています。つまり、それらはソート順に対してカウントされず、比較は代わりに次の文字に移動すべきです。 utf8mb4_unicode_ci はこれらを適切に処理します。

アジア言語や異なるアルファベットを持つ言語など、非ラテン語圏の言語では、多くの場合 より ユニコードのソートと簡略化された utf8mb4_general_ci ソートされます。 の適否は utf8mb4_general_ci は、使用する言語に大きく依存します。 ある言語では、かなり不十分なものになるでしょう。

何を使うべきですか?

を使用する理由はほとんどないでしょう。 utf8mb4_general_ci CPU速度が十分に低く、パフォーマンスの違いが重要である点を置き去りにしてしまったからです。 データベースは、これ以外のボトルネックによって制限されることはほぼ間違いないでしょう。

以前は utf8mb4_general_ci ただし、正確なソートがパフォーマンスコストを正当化するのに十分なほど重要であった場合を除きます。 今日、このパフォーマンスコストはほとんどなくなっており、開発者は国際化をより真剣に扱うようになっています。

正確さよりもスピードを重視するのであれば、ソートは一切しないほうがいいという議論もあります。 正確さを求めないのであれば、アルゴリズムを高速化することは些細なことなのです。 というわけで。 utf8mb4_general_ci は、速度の理由ではおそらく必要なく、精度の理由でもおそらく適さない妥協案です。

もうひとつ付け加えると、アプリケーションが英語しかサポートしていないとわかっていても、人名を扱う必要がある場合があります。人名には、他の言語で使われる文字が含まれていることが多く、その場合は正しくソートすることが同様に重要です。 すべてにUnicodeのルールを使用することで、非常に賢いUnicodeの人々が、ソートが正しく動作するように一生懸命働いてくれたという安心感を得ることができます。

各パーツの意味

まず最初に ci 大文字小文字を区別しない ソートと比較。 つまり、テキストデータに適しており、大文字・小文字は重要ではありません。 他の照合順序の種類は cs (大文字と小文字を区別する) が重要なテキストデータの場合、および bin エンコーディングがビット単位で一致する必要がある場合、これは実際にエンコードされたバイナリデータ(例えばBase64を含む)であるフィールドに適しています。 大文字小文字を区別してソートすると奇妙な結果になり、大文字小文字を区別して比較すると、文字の大文字小文字だけが異なる重複した値になってしまうので、大文字小文字を区別する照合順序はテキストデータでは好まれなくなりつつあります。

次に unicode または general は、特定のソートや比較のルール、特にテキストを正規化したり比較したりする方法を指します。 utf8mb4 文字エンコーディングには、さまざまな規則があります。 unicodegeneral この2つは、特定の1つの言語ではなく、すべての可能な言語でうまく機能するように試みられています。 この2つのルールの違いが、この解答の主題です。 なお unicode は、Unicode 4.0 のルールを使用しています。 最近の MySQL のバージョンでは unicode_520 はUnicode 5.2のルールを使用し、そして 0900 ("unicode_" の部分を削除) Unicode 9.0 の規則を使用しています。

そして最後に utf8mb4 はもちろん、内部で使用する文字コードです。 この回答では、Unicodeベースのエンコーディングについてだけ話します。