2012-09-16 17 views
12

latin1を使用してutf8を文字セットとして使用する場合のメリットとデメリットは何ですか?utf-8 vs latin1

utfがより多くの文字をサポートでき、一貫して使用されていれば、いつもより良い選択ではないでしょうか? latin1を選択する理由はありますか?

+0

utf8mb4ではなく、常にutf8mb4を使用してください(https://medium.com/@adamhooper/in-mysql-never-use-utf8-use-utf8mb4-11761243e434)。 )。 – xmedeko

答えて

10

latin1は、1バイトエンコーディングであるという利点があります。したがって、MySqlの文字列データ型の長さがエンコーディングに依存するため、同じ記憶領域に複数の文字を格納できます。マニュアルstates

特定のCHAR、 VARCHAR、またはTEXTの列の値を格納するために使用されるバイト数を計算するには、あなたのアカウントに、その列に使用 文字セットを取る必要があり、値が が含まれているかどうかということマルチバイト文字。特に、utf8(またはutf8mb4) ユニコード文字セットを使用する場合、すべての文字が同じバイト数を使用しているわけではなく、1文字につき最大で3バイト(YYYY)である必要があることに注意する必要があります。異なる のutf8またはutf8mb4文字のカテゴリに使用されるストレージの内訳は、第10.1.10項「 「Unicodeサポート」」を参照してください。

さらに、1バイトのエンコーディングでは、文字列操作(サブストリングの取得や照合依存の比較など)が多く行われます。

いずれにしても、国際化を気にすると、latin1は深刻な候補にはなりません。既知の安全な値(パーセントでエンコードされたURLなど)を格納するときは、適切な選択肢となります。

+0

他のUnicode言語もサポートしていますか?ヘブライ語特に? – qwertymk

+0

ヘブライ語の@qwertymkはサポートしていません。スクリプトのリストについては、http://en.wikipedia.org/wiki/ISO/IEC_8859-1を参照してください。 –

+0

@qwertymk:明らかに[not](http://dev.mysql.com/doc/refman/5.5/en/charset-we-sets.html)、西欧の文字セットと呼ばれています。 – Jon

1

latin-1のような固定長エンコーディングは、常にCPU消費の面でより効率的です。

いくつかの固定長文字セットのトークンセットが目的のために十分であることがわかっていて、LENGTH()とSUBSTR()のものがたくさんある重く集中的な文字列処理が必要な場合は、これは、UTF-8などのエンコーディングを使用しない理由がある可能性があります。

ああ、そしてBTW。文字セットとを符号化している間に、そうであるように混同しないでください。文字セットは、書き込み可能なグリフの定義済みのセットです。同じ文字セットに複数の異なるエンコーディングを設定できます。ユニコード標準のさまざまなバージョンは、それぞれ文字セットを構成します。それぞれは、UTF-8、UTF-16、および「UTF-32」(公式の名前ではありませんが、任意の文字に完全な4バイトを使用するというアイデアを指します)エンコーディングを受けることができ、後者はそれぞれHOBファーストまたはHOBラストフレーバーで来てください。

15

UTF8利点:

  1. は、ヘブライ語などのRTL言語を含むほとんどの言語をサポートしています。

  2. UTF8対応コンポーネント(JavaScript、Javaなど)にデータをインポート/エクスポートするときには、翻訳が必要ありません。

UTF8短所:

  1. 非ASCII文字は、そのより複雑な符号化方式に、エンコードとデコードに時間がかかります。

  2. 非ASCII文字は、1バイト以上(ASCII文字セットの最初の127文字以外の文字)を使用して格納されるため、より多くの領域が必要です。 CHAR(10)またはVARCHAR(10)フィールドは、UTF8文字を格納するために最大30バイト必要です。ソート順は、直接)文字符号化順序にマップしないだろう、とutf8_general_ci照合への変数のデフォルトとして、いくつかのストアドプロシージャ()での翻訳が必要になりますようutf8_bin以外

  3. 照合順序が遅くなります。あなたはJOIN UTF8とUTF8以外のフィールドに必要がある場合

  4. 、MySQLはSEVEREパフォーマンスヒットを課します。サブ秒のクエリは、結合されたフィールドが異なる文字セット/照合である場合、を受け取る可能性があります。

ボトムライン:

あなたは、非Latin1の言語をサポートする必要が最大のパフォーマンスを達成したい、またはすでにlatin1を使用してテーブルを持って、latin1を選択しない場合。

それ以外の場合は、UTF8を選択します。

+1

"VARCHAR(10)はUTF8データの5文字以下の文字しか格納できないため、追加スペースを確保するために' CHAR'フィールドの長さを増やす必要があるかもしれません。 (不利な点1)が間違っています。列のサイズは、ストレージのサイズではなく、許容される最大文字数を反映します(http://dev.mysql.com/doc/refman/5.6/en/storage-requirements.htmlを参照)。 –

+0

meden:あなたは絶対に正しいです。私はこの事実を反映するために私の答えを更新しました。間違って申し訳ありません。 –

+0

ASCIIについてはどうですか?ラテンの代わりに –

2

@ロススミスII、ポイント4は価値があり、列間の不一致が危険である可能性があることを意味します。

はすでに良い答えに値を追加するには、ここでの文字セットの違いについての小さな性能試験である:

20000行、懸念の列には、インデックス付きのモダンな2013サーバー、実際の使用テーブル。

SELECT 4 FROM subscribers WHERE 1 ORDER BY time_utc_str; 15msの

  • VARBINARY(20):17ms
  • utf8_bin:20msの
  • utf8_general_ci:23MS
    • VARCHAR(20)文字セットLATIN1 COLLATION latin1_bin(4キャッシュバスターです)数値的な日付のような単純な文字列の場合、私の判断は、パフォーマンスに関して、utf8_bin(文字セットutf8のCOLLATE utf8_bin)を使用することです。これにより、データベースの文字セットがutf8であると予想される他のコードに悪影響を及ぼすのを防ぐことができます。

    関連する問題