web-dev-qa-db-ja.com

Postgres-エンコーディング、照合、CType

                                                        List of databases 
          Name           |  Owner   | Encoding |          Collate           |           Ctype            |
-------------------------+----------+----------+----------------------------+----------------------------|
 MyDatabase              | postgres | UTF8     | English_United States.1252 | English_United States.1252 |

誰かがエンコーディング、照合、Ctypeが互いにどのように関連しているか説明できますか?

エンコーディングは、情報が実際に格納される方法に影響することを知っています(つまり、「A」が1バイトを必要とするか複数バイトを必要とするか、およびそれらのバイトの値はエンコーディングによって異なります)。

Collat​​eは文字を比較するためのルールを指定すると言われています。一連の文字列を並べ替える場合は、照合タイプによって順序が決まります。

Ctypeとは何かを見つけるのに苦労しました。大文字や小文字などの概念に関連している可能性があります(「A」が大文字の形式であることを知っている「a」が与えられている場合)。

(私の例のように)UTF8でエンコードされたデータベースを作成し、照合値として英語1252を使用する方法がわかりません。UTF8には、win1252にはない多くの文字があります。それらを並べ替えたり比較したりするとどうなりますか?私の現在のセットアップは無意味です......常にエンコーディング/照合/ Cタイプに同意したいようです?

5
Rob P.

エンコーディングは、情報が実際に格納される方法に影響することを知っています(つまり、「A」が1バイトを必要とするか複数バイトを必要とするか、およびそれらのバイトの値はエンコーディングによって異なります)。

はい。エンコーディングは、文字からバイトへの変換アルゴリズムです。 LATIN1などのモノバイトエンコーディングの場合、それは自明なバイト値=文字数ですが、UTF-8の場合はより複雑です。

Collat​​eは文字を比較するためのルールを指定すると言われています。一連の文字列を並べ替える場合は、照合タイプによって順序が決まります。

はい、collat​​eは文字列の比較方法を指定します。照合サービスは、オペレーティングシステムまたはオプションでPostgreSQL 10以降のICUライブラリによって提供されます。言語ルールによる任意の文字列のソートは複雑なビジネスです。Unicode標準とISOはルールを提供していますが、高度にカスタマイズ可能であり、すべてのCライブラリがそれらを完全に実装しているわけではありません。たとえば、詳細については https://en.wikipedia.org/wiki/Unicode_collat​​ion_algorithm を参照してください。

Ctypeとは何かを見つけるのに苦労しました。大文字や小文字などの概念に関連している可能性があります(「A」が大文字の形式であることを知っている「a」が与えられている場合)。

POSIXのLC_CTYPEは ctype.h の関数に関連しています。PostgresはPOSIXの影響を強く受けており、データベースごとにlc_ctypeを使用していますPOSIXが使用しているようにLC_CTYPE

Upper()およびlower()のほかに、正規表現および全文検索(トークンの大文字小文字変換)にも関連しています。

Postgresは(lc_collat​​eと同じ値を使用して)独立したlc_ctypeなしでできると思いますが、1つだけ例外があります。たとえば、lc_ctypesomething.UTF-8を使用すると、すべての文字を適切にサポートできます、およびlc_collateからCへの変換は、照合としてのCは、lc_collate=lang_country.UTF-8が暗黙的に示す言語ソートよりもはるかに高速であるためです。

Robert Haas(postgresコミッター)は、PostgresでCOLLATEサポートが強化されたときに、本質的にその主題について興味深い投稿を書きました: "The Perils of Collat​​ion-Aware Comparisons"

(私の例のように)UTF8でエンコードされたデータベースを作成して、英語の1252の照合値を使用する方法がわかりません。UTF8には、win1252にはない多くの文字があります。

これはWindows固有のものです。これは、Windowsがロケールと照合順序を含むPOSIXモデルに従っていないためです。 Windowsおよび非ICU照合で、Postgresは文字列をdbエンコーディングからUTF-16(wchar_t)に変換し、 wcscoll_l() を呼び出します。これが、照合が照合と非相関である理由です。

ICU照合順序では、Postgresが可能な場合は直接UTF-8コンテンツを渡すか、文字列をUTF-16に変換するため、照合順序は特定のデータベースエンコーディングに関連付けられていません。 POSIXモデルとそのstrcoll関数ファミリー。

8
Daniel Vérité