UTF-8(および多分UTF-16 / UTF-32)以外の文字エンコーディングは非推奨ですか?


31

私の大嫌いな人は、文字セットをサポートするための山のようなコードを持つ非常に多くのソフトウェアプロジェクトを見ています。誤解しないでください、私はすべて互換性があるので、テキストエディタを使用して複数の文字セットでファイルを開いたり保存したりできることを嬉しく思います。私を悩ますのは、非ユニバーサル文字エンコーディングの急増が「問題」ではなく「適切なUnicodeサポート」とラベル付けされていることです。

たとえば、PostgreSQLとその文字セットサポートを選択します。PostgreSQLは2種類のエンコーディングを扱います。

  • クライアントのエンコード:クライアントとサーバー間の通信で使用されます。
  • サーバーのエンコード:データベースにテキストを内部的に保存するために使用されます。

多くのクライアントエンコーディングをサポートすることが良いことである理由を理解できます。UTF-8で動作しないクライアントは、変換を実行する必要なくPostgreSQLと通信できます。取得できないのは、PostgreSQLが複数のサーバーエンコーディングをサポートしている理由です。データベースファイルは(ほとんどの場合)PostgreSQLバージョン間で互換性がないため、ここではバージョン間の互換性は問題になりません。

UTF-8は、すべてのUnicodeコードポイントをエンコードできる唯一の標準のASCII互換文字セットです(間違っている場合はお知らせください)。私は、UTF-8が最高の文字セットであるという陣営にいますが、UTF-16やUTF-32などの他のユニバーサル文字セットに我慢します。

すべての非ユニバーサル文字セットは廃止されるべきだと思います。彼らがすべきではない説得力のある理由はありますか?


4
@mario:UTF-8の元の定義では6バイトまで許可されていました。後に、UTF-16がサポートできる文字のみをカバーするように人為的に制限されました。
dan04

6
少なくともPostgreSQLは、意図的に複数の文字エンコーディングを処理します。誰かが気にしなかったので、UTF-8とwindows-1252のランダムな組み合わせを処理する必要があるのはうんざりです。
dan04

5
@ dan04:ロシア語のテキストを操作するのは苦痛でした。これは、大幅に異なる複数のエンコーディングを使用し、通常は異なるフォントを使用して動作するようにハッキングするためです(多くの場合、メタデータで使用されているエンコーディングについて嘘をつきます)。全体として、恐ろしい混乱です。おそらくUTF-8に移行することで、その方向からのサポートリクエストの数がすぐに減少したため、それらはクリーンアップされたと思われます。
ドナルドフェローズ

3
理論的なUnicodeの範囲は0〜0x10ffffです。これ以上何もない。それがUnicode規格の言っていることです。UTF-8はすべてのUnicodeを処理し、常に処理します。ユニコードではないエンコーディングの仮想的な範囲はカバーしませんが、ユニコードのすべてをカバーします。
gnasher729

回答:


16

PostgreSQLについて述べたので、いくつかの権限で、UTF8以外のサーバー側エンコーディングがこのように詳細にサポートされている主な理由は、日本人がそれを必要としているということです。どうやら、Unicodeとさまざまな日本の「レガシー」エンコーディングとの間の同一の往復変換が常に可能とは限らず、場合によってはベンダー間で変換テーブルが異なることさえあります。それは本当に困惑していますが、明らかにそうです。(広範な文字セットのサポートも、PostgreSQLが日本で非常に人気がある理由の1つです。)

データベースシステムについて説明しているので、主な仕事の1つは、ユーザーが定義したとおりにデータを確実に保存および取得できるようにすることです。そのため、損失のある文字セット変換が飛ぶことがありません。たとえば、Webブラウザーを扱っている場合、本当に重要なのは結果問題ないように見えるかどうかです。おそらく、サポートするエンコードの数を減らすことはできますが、データベースシステムでは追加の要件があります。

他の回答で言及された他の理由のいくつかは、支持する議論としても当てはまります。しかし、日本人が拒否している限り、キャラクター設定のサポートを減らすことはできません。


したがって、これらのエンコーディングのために、テキストのUTF-8への変換と逆変換は一般に損失がありますか?(6か月後からではなく)すぐに変換が戻されたとしても?
ジョーイアダムス

ジョーイ・アダムス:どうやらそう。
ピーターアイゼントラウト

3
Googleが「ハン統合」の理由を確認
Petr Viktorin

7

明らかな2つの理由:保存しているデータによっては、別の形式への変換にかなりの時間と余分なスペースが必要になる場合があります。400メガバイトの情報を保存する場合、ストレージ要件を2倍にすることは大したことではありませんが、400テラバイトを保存する場合は、もう少し意味があります。400テラバイトのデータを(たとえば)Shift-JISからUTF-xに変換するのにも少し時間がかかります。

これは、たとえば、データベースが特定の年のうち、たとえば10分間を除くすべての時間で使用可能であり、1秒間に数百回更新されるデータベースがあるという稼働時間の保証がある場合、特に困難になります。ただし、このような状況でもメジャーコンバージョンを管理することは可能ですが、軽視することはできません。場合によっては、そのような変換の準備をするのに数年の計画が簡単にかかる可能性があります。

(たとえば)ASCIIのみをサポートするデータベースから始めている場合、これらすべてのエンコーディングのサポートを追加することが理にかなっているかどうかを議論する正当な理由があるかもしれません -しかし、すでにそれらをサポートしている場合、ドロップすることから得られるものはほとんどありませんそれらのサポート。

特に、コードを単純化する方法などでは、ほとんど何も得られないことに注意してください。とにかくクライアントとサーバー間の変換を処理するには、すべての変換ルーチンが必要です。そのため、サポートを削除するということは、「ディスクへの書き込み」および「ディスクからの読み取り」パスで1つの(マイナー)関数呼び出しを削除することを意味しますが、(他の場合は)ほとんどありません。ディスク上で2つのエンコーディングをサポートしていても、それを得ることさえできません-関数呼び出しがまだあるので、あなたが本当にやるべきことは、その関数でサポートされているエンコーディングの範囲を制限することです。

少なくともこれを設計する場合は、おそらくUCS-4で動作するデータベースのコアを作成し、コアとディスク間、およびコアとユーザー間で変換ルーチンを作成することになります。どちらの場合も同じルーチンセットを使用するため、最も簡単なルートは、クライアントが使用を許可されたのとまったく同じエンコーディングセットをディスクストレージで使用できるようにすることです。


1
Shift-JISは自己同期ではないため、検索が面倒です。あなたは考え、それをサポートしていないことにより、大幅な簡素化を得ることができます。
dan04

@ dan04:すでに実績のあるShift-JISの検索/インデックス作成ルーチンがある場合、UTF-8またはUCS2に切り替えると、パフォーマンスが大幅に改善される可能性があります。以下のために新しいデータベースあなたはUCS2またはUTF-16のような、より良い、より便利に、定期的なエンコーディングを、選択することがあります。
9000

@ dan04:それをまったくサポートしなくても大丈夫なら、かなりの利益が得られるでしょう。限り、あなたはそれがから来る/クライアントに行くのサポートとして、あなたは...その醜さのほとんどで立ち往生するつもりだ
ジェリーの棺

5

サーバーにUTF-8のみを保存する場合、いくつかの問題があります。

  1. VARCHAR(20)列の制限は何ですか?それは20バイトですか、それとも20の「文字」ですか(Unicodeでは、文字、合字などの組み合わせを考慮した場合の「文字」とは何ですか?)。さらに悪いことに、CHAR(20)可能なスペース全体を実際に確保する必要がある場所についてはどうでしょうか。MySQLではCHAR(20)、最悪のケースを処理するためだけに、UTF-8エンコード列のバイト数の4倍(つまり80バイト)を確保しています。
  2. サーバーエンコーディングとクライアントエンコーディングの間で、一定のエンコーディング変換を実行する必要があります。複数のクライアントエンコーディングのサポートを停止することもできますが、そうしない限り、すべての文字列を常に変換する必要があります。サーバーのエンコードとクライアントのエンコードを一致させることができる場合、変換は必要ありません。
  3. 他の人が指摘しているように、UTF-8は英語のテキストを保存するのに非常に効率的ですが、他の言語、特に東アジア言語には非常に非効率的です。スーツとしてUTF-16またはUTF-8の使用を許可することができると思います。または、テキストを圧縮しますが、インデックス作成と検索が非効率的になります。

そうは言っても、私はあなたに同意します。レガシーエンコーディングはほとんど無意味であり、一般的にUnicodeはすべての新しいアプリケーションに使用するのに最適なエンコーディングです。今日データベースデータベースをゼロから作成する場合、Unicodeのみをサポートし、レガシーエンコーディングは一切サポートしません。

違いは、現在使用されているPostgreSQLと他のほとんどのデータベースサーバーは、Unicodeが実行可能なオプションになるから存在していたことです。そのため、彼らはすでにレガシーエンコーディングをサポートしていました(もちろん当時はレガシーではありませんでした)。


10
「しかし、それは他の言語、特に東アジア言語にとっては非常に非効率的です」 実際にも?考えてみましょう。この中国のWikipediaのページを。それは非常に多くの中国語の文字を表示しますが、ページのソースでは、ASCII文字がほぼ7:1を圧倒します。
ジョーイアダムス

2
CHAR(N)列のNが明確に定義された識別子形式の一部である場合(たとえば、VINが正確に17文字に定義されている場合)、おそらく文字や合字を組み合わせる必要はありません。そうでない場合、Nは任意の制限であり、データの切り捨てを避けるために寛大に解釈する必要があります。
dan04

5
@Joey Adams:それは、マークアップ自体がテキストの大部分を占めるHTMLおよびXMLに当てはまります(そして、UTF-8がWebに適していると思う理由です)が、データベースにはあまり保存しませんHTML。結局のところ、それは2倍(またはそれ以下)の違いにすぎず、実際にはそれほど違いはありません。
ディーンハーディング

5
この回答の箇条書き#2は無関係です。ユニコードが使用されているかどうかに関係なく適用されます。箇条書き3は、非効率性とその範囲を完全に誇張しています。同時に、この回答は、レガシーエンコーディングによって引き起こされる問題を大幅に控えめにしています。人生で使うのが英語だけなら、問題はそれほど大したものではないと推測するのは簡単です。
ティムウィ

2
@Dean:自分の投稿をせずに回答にコメントできないことを知りませんでした。
ティムウィ

3

非ユニバーサル(具体的にはシングルバイト)エンコーディングには、次の場所があります。

  • Unicode文字データベースを保存するのに十分なメモリがありません。
  • ROMにハードコードされたシングルバイトフォントを使用します。
  • 異なってエンコードされたファイルのソースを提供するためのインターネットアクセスがありません。

これは、一部の種類の組み込みデバイスに今日当てはまります。しかし、デスクトップ上およびサーバールームでは、非Unicodeエンコーディングは長い間廃止されるはずです。


3
私はそのような家庭用コンピューターを使用していました。私は80年代初期にそれらのほとんどを取り除きました。
デビッドソーンリー

2

UTF-8は、エゴセントリックな1人の英語を話す人に最適です。日本人の場合、文字の約99%はUTF-16の2つではなく3〜4バイトかかります。

非ラテン方言は、サイズレベルでUTF-8の影響を本当に受けます。数年以内に、ほとんどのクライアントは中国語であり、中国語の文章には数百万の文字があることを忘れないでください。UTF-8ではこれを効率的に維持できません。

それ以外の場合、UTF- 何かではないテキスト文書を持っているときは嫌いです。適切なエンコードを行う必要がある場合は、しばしば邪魔になりません。私の本では、非Unicodeエンコーディングは死んでいます。

1.自己中心的な部分を個人的にとらないでください。私はカラフルなイラストを作りたかったのですが、それは本当の意味ではありません。


3
@Matthew-4xは明らかにxの4倍です(正のxの場合)。ここでは、漸近記法がどのように関連するのかわかりません。漸近的な成長率で宣伝されているハードディスクを見たことがありません。通常、サイズはドライブの寿命を通して同じままです。
Steve314

3
とにかく数百万の文字はUnicodeに適合しません。ウィキペディアの記事によると、現在約6万人の漢字があります。Unicodeは単なる中国語ではないため、かなりの数の中国語の文字がUTF-16で4バイトを必要とすることを意味します。これは、現在のUTF-8の長さです。UTF-8およびUTF-16の中国語テキストの長さに関する統計を見るのは興味深いでしょう。
デビッドソーンリー

6
@David:すべての日本語および中国語の文章の> 99%は、UTF-16では2バイト、UTF-8では3バイトのみを必要とする文字を使用しています。より多くを必要とするキャラクターは非常にまれで、歴史的です。
ティムウィ

8
一般に、日本語と中国語では単語あたりの文字数が少ないことに注意してください。私は、すべてがutf-8でエンコードされた英語、日本語、中国語の大きな言語ファイルを持つアプリを使用しています。実際、中国語のファイルは最も小さく、日本語のファイルは英語のオリジナルよりも約15%大きくなっています。
ロボットを

3
ナンセンス。UTF-16で2バイトを使用するものはすべて、UTF-8で3バイトを超えません。UTF-8で4バイトであるものはすべて、UTF-16で4バイトです。漢字の「何百万」も存在せず、明らかに16ビットに収まりません。
gnasher729

1

Unicodeは根本的に壊れており、修正されることはほとんどありません。より良いもの、真に普遍的なものに置き換える必要があります。廃止が必要なものがあれば、それはUnicodeです。

Unicideの問題の例:

  • UTF8は妥当なハックですが、ほとんどのUTF16ベースのソフトウェアは壊れています。UnicodeをサポートするほとんどのWindowsアプリは、OS自体を含めてUTF16を使用します。最も一般的な問題は、基本的なプレーン、つまり複数単語の文字以上をサポートしていないことです。

  • 漢統一は、軽減されない災害です。追加のメタデータなしで日本語/中国語/韓国語のテキストを単一のドキュメントに混在させることは不可能であり、使用するフォントを検出することは困難です。

  • 組み合わせキャラクターは別の災害です。より賢明なエンコーディングスキームは、1つの文字を1つのコードにマッピングするため、文字列の処理が比較的健全になります。Unicodeはサポートしていません。Unicodeは一貫性さえありません-漢字はほとんど組み合わせですが、ヨーロッパの組み合わせ文字のようにそのようにエンコードされません。

  • 一部の人々の名前はユニコードで正しく記述できないか、上記の問題のために誤ってレンダリングされる傾向があります。これは、航空券に(誤って)印刷されているものと一致しないパスポートで航空機に搭乗しようとする場合など、深刻な結果を招く可能性があります。

これらの問題などにより、英語以外のソフトウェアの多くはUnicodeを使用できず、ローカルの文字エンコーディングに依存しています。これは、特に日本語および中国語のソフトウェアで一般的です。

理想的には、Unicodeは非推奨です。TRON文字コーディングは、Unicodeのかなり良い代替品であり、更新されない既存のソフトウェアとほぼ互換性があります。


さまざまな文字のバリエーション(日本語/韓国語/中国語)を混在させることは不可能であるというあなたの主張は、2002年のUnicode 3.2標準である15年以来古くなっているようです。表示されるはずです。また、組み合わせ文字は、「発音区別符号と基本文字(a°)および特殊グリフ(å)の組み合わせ」として指定され、それらを逆に変換するプロセスは「正規化」です。そのため、Unicodeは根本的に壊れていません。
トーステンS.

多くの欠陥を説明します。組み合わせ文字を使用する言語と使用しない言語があり、Unicodeはどちらを優先するかを決定できません。私が指摘したように、ユニコードをサポートすると主張するほとんどのソフトウェアは、とにかくこれらの問題を理解せず、セレクターを使用しても間違って表示します。プログラマは、言語の専門家であると期待されるべきではありません。これは、Unicodeのもう1つの基本的な欠陥です。
ユーザー

0

たぶん書くためではなく、読むためです。

これらのエンコーディングを使用する既存のコンテンツがたくさんあります。また、base64のような一部のエンコーディングは、バイナリデータを埋め込む方法としてテキストプロトコルを義務付けているため、どこにも行きません。

本当の問題は、セキュリティホールにつながるエンコーディングの自動検出です。UTF-7のような不明瞭なエンコーディングが消えるのを見るのは気になりません。

また、自動検出は、単純にバイト文字列を連結して生成されるコンテンツを不適切に処理する傾向があります。


7
Base64は文字エンコードではありません。
dan04

0

データベースと新しいアプリケーションのデフォルトの文字エンコーディングは、ある種のUTFバリアントでなければならないことに同意できます。私は個人的にはUTF-16を選択します。これは、スペースと複雑さ(UTF-8よりも)の合理的なトレードオフのようです。ただし、特定の場合には、一部の文字エンコードが依然として意味をなします。

  • base64テキストを保存/転送する場合、必要なのはASCIIだけで、電子メールなどの7ビットでエンコードされたプロトコルを使用することもできます。UTF-8の余分なオーバーヘッドは不要です。
  • これらの古い文字エンコーディングに基づいていくつかのファイルと既存のデータが構築されているため、それらを読み取ることができることが重要です。

4つの標準UTF正規化アルゴリズムがあることに注意してください。マルチコードポイント文字が心配な場合は、2つの正規化アルゴリズムのいずれかを使用して、それらを同等の単一コードポイント文字にまとめることができます。それらの違いは、文字の論理的同等性と物理的同等性に関係しています。


1
ダウンボッターは、ダウンボットした理由を説明できますか?
ベリンロリチュ

3
ダウン票はしませんでしたが、base64のポイントは、バイナリデータをテキストチャネルに転送することです。そのチャネルで使用するエンコードを選択できる場合、テキストエンコードはまったく使用しません。チャンネルが本当にプレーンASCIIであっても、Base 64は7ビットのうち6ビットしか使用していません-すでにかなりのオーバーヘッドです。
Steve314

誰かが箇条書きだけを読んでいないことを願っています。これらは、UTFの使用の例外でした。また、8バイトのうち6バイトのみを使用するBase 64については間違っています。ASCII「文字」の最初のセットは、印刷できない制御文字であり、base64の一部の文字が8バイトのうち7バイトを使用するように強制します。これらのすべての文字がすべてのコードページに存在することが保証されているわけではないため、0〜127の文字は存在するため、意図的に上位ビットを回避します。
ベリンロリチュ

2
@Berin-(1)いいえ、しかし、「同意する」ものは箇条書きなしではあまりありません。(2)base 64には64の「数字」があります。2 ^ 6 == 64であるため、64桁は6ビットの価値があります。7ビットのコード空間(または8ビット、または必要に応じて8バイト)でそれをどのように表現するかは、実際にそこにあるデータ量とは異なります。非印刷文字などを避けることがオーバーヘッドの理由です-オーバーヘッドが存在しないという意味ではありません。バイナリデータ用に設計されたチャネルを選択すると、そのオーバーヘッドはありません。
Steve314

3
base64は、テキストのみのチャネルを介してバイナリデータを送信することに対処するために考案されたことに留意してください。非効率的(3:4の拡張)であることが知られていますが、特定のトランスポートオプションの技術的な制限に対処します。レガシーは電子メールとUseNetフォーラムですが、最新のアプリケーションではバイナリデータをXMLに埋め込みます。適切なチャネルが存在しない場合があり、既存のチャネルの制限を克服する必要があります。
ベリンロリチュ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.