IMEIは携帯電話を一意に識別することを目的とした15桁の番号です。1990年代に携帯電話が登場した際、非常に高価な携帯電話が盗難されて悪用されるケースを想定し、欧州で携帯電話の端末に「一意で管理可能なコード」の設定が義務付けられ、携帯電話メーカーや通信事業者の業界団体であるGSMアソシエーションがIMEIの仕様を開発しました。
⇧ デバイスの電源がOFFになっていても、デバイスの追跡とかできるんかね?
PostgreSQLのデータベースの文字セットについて調べてみる
とりあえず、UTF8にしておけば良いと思ったのだけど、詳しく調べたことなかったなと思ったので、調べてみる。
日本語化されたPostgreSQL 公式のドキュメントによると、
24.3. 文字セットサポート
PostgreSQLの文字セット(エンコーディングとも呼ばれます)サポートにより、ISO 8859シリーズなどのシングルバイト文字やEUC(拡張Unixコード)、UTF-8、Mule内部コードなどのマルチバイト文字を含む、各種文字セットでテキストを保存できます。
全ての文字セットはクライアントにより透過的に使用できますが、いくつかは、サーバ内での(つまりサーバサイドエンコーディングとして)使用はサポートされていません。デフォルトの文字セットは、initdb
を使用したPostgreSQLデータベースクラスタの初期化時に決定されます。 これは、データベースを作成する時に上書きできるので、異なる文字セットを使用した複数のデータベースを持つことができます。
⇧ とのこと。
分かり辛いのだけど、
⇧ Oracle Databaseと同じく、PostgreSQL ではデータベース作成時にしか文字セットを指定できず、後から変更ができないということで良いかと。
PostgreSQLでデータベースを作成する時のオプションはと言うと、
CREATE DATABASE name [ WITH ] [ OWNER [=] user_name ] [ TEMPLATE [=] template ] [ ENCODING [=] encoding ] [ STRATEGY [=] strategy ] ] [ LOCALE [=] locale ] [ LC_COLLATE [=] lc_collate ] [ LC_CTYPE [=] lc_ctype ] [ ICU_LOCALE [=] icu_locale ] [ LOCALE_PROVIDER [=] locale_provider ] [ COLLATION_VERSION = collation_version ] [ TABLESPACE [=] tablespace_name ] [ ALLOW_CONNECTIONS [=] allowconn ] [ CONNECTION LIMIT [=] connlimit ] [ IS_TEMPLATE [=] istemplate ] [ OID [=] oid ]
⇧ となっている。
基本的には、
それによると、PostgreSQL 8.3以降でJIS X 0213:2004をUTF_8にてサポートしていて、EUC_JIS_2004やSHIFT_JIS_2004というエンコーディング名において相互変換できるようになっているそうだ。
⇧ENCODINGをUTF_8にしておくしか無さそう。
あとは、LOCALEなんだけど、
⇧ いまいち、PostgreSQL のデータベースにおける文字セット、LOCALE、ENCODINGの用語の関係性がハッキリしない...
24.3. 文字セットサポート
PostgreSQLの文字セット(エンコーディングとも呼ばれます)サポートにより、ISO 8859シリーズなどのシングルバイト文字やEUC(拡張Unixコード)、UTF-8、Mule内部コードなどのマルチバイト文字を含む、各種文字セットでテキストを保存できます。
encoding
新しいデータベースで使われる文字セット符号化方式です。 文字列定数(例えば'SQL_ASCII'
)、整数の符号化方式番号、DEFAULT
のいずれかを指定します。 DEFAULT
とすると、デフォルトの符号化方式(すなわちテンプレートデータベースの符号化方式)を使います。 PostgreSQLサーバでサポートされる文字セットについては24.3.1で説明します。 この他の制限については後述します。
⇧ なるほど、ドキュメント内で用語の意味合いが異なるらしく、
- 日本語の「エンコーディング」
→文字セット - 英語の「encoding」
→文字セット符号化方式
ってことになるらしい。
で、PostgreSQL のデータベースにおけるLOCALEはと言うと、
locale
これはLC_COLLATE
とLC_CTYPE
を一度に設定する手っ取り早い方法です。
https://www.postgresql.jp/docs/15/sql-createdatabase.html
⇧ とあり、
lc_collate
新しいデータベースで使用する照合順(LC_COLLATE
)です。 これは、たとえばORDER BYを持つ問い合わせなどにおいて文字列に適用されるソート順やテキスト型の列に対するインデックスで使用される順序に影響します。
https://www.postgresql.jp/docs/15/sql-createdatabase.html
lc_ctype
新しいデータベースで使用する文字のクラス(LC_CTYPE
)です。 これは、たとえば小文字、大文字、数字といった文字の分類に影響します。 デフォルトではテンプレートデータベースの文字クラスを使用します。 さらなる制限に関しては後で説明します。
https://www.postgresql.jp/docs/15/sql-createdatabase.html
⇧ とあるのだけど、ソート順とかが関係してきますと。
少し、話が脱線するのですが、
initdb
はPostgreSQLのデータベースクラスタを新しく作成します。 データベースクラスタとは、1つのサーバインスタンスで管理されるデータベースの集合です。
⇧と言う説明があり、公式のドキュメントではないのだけど、
⇧ 上記サイト様のイメージ図を見た感じでは、
- initdb
→データベースクラスターを作成する - CREATE DATABASE
→データベースを作成する
ってことになるかと。
一応、各々のデータベース(CREATE DATABASEを実行して作る方)で文字セットは変えることはできるのだけど、作成時にしか指定できず、後からの変更が不可であると、「株式会社コーソル」の方のサイトで仰っておりましたな。
で、PostgreSQL におけるLOCALEの話に戻ると、
24.1. ロケールのサポート
ロケールのサポートはアルファベット、並び換え、数字の書式など文化的嗜好を配慮したあるアプリケーションを対象にします。 PostgreSQLは、サーバのオペレーティングシステムが提供する、標準ISO CとPOSIXのロケール機能を使用します。 これ以上の情報についてはお使いのシステムのドキュメントを参照ください。
英語の照合順序規則でスペイン語のメッセージを使用する時など、時として複数のロケールの規則を併用すると便利です。 これをサポートするために、ロケールには以下のような多言語対応規則の特定の箇所だけを管理する一連のサブカテゴリがあります。
一部のロケールカテゴリでは、その値がデータベース生成時に固定されていなければならないものがあります。 他のデータベースで他の設定を使用することができますが、一度データベースが生成されると、そのデータベースでは変更することができません。 LC_COLLATE
とLC_CTYPE
がこれらのカテゴリにあてはまります。 これらはインデックスのソート順に影響を及ぼすため、固定されていなければなりません。 さもないと、テキスト型の列上のインデックスは破壊されるでしょう。 (しかし24.2内で述べられているように、照合順序を使用することで、この制限を緩和できます)
initdb
が実行された時に、これらのカテゴリのデフォルト値は決定され、CREATE DATABASE
コマンドで他を指定しない限り、新しいデータベースが作成されるときにこの値が使用されます。
その他のロケールカテゴリは、いつでも、ロケールカテゴリと同じ名前の実行時パラメータを設定することで、希望値に変更できます (詳細は20.11.2を参照してください)。 initdb
で選択された値は、実際のところ、サーバの起動時にデフォルトとして動作するようにpostgresql.conf
設定ファイルに書き込まれるだけです。 この代入文をpostgresql.conf
から削除すると、サーバは実行環境の設定をそのまま使用します。
⇧ 何やら、initdbで選択された値は、postgresql.confで変更できるような書きっぷりがある...
データベースクラスターの方の設定は、後から変更が可能ってことですかね?
ちなみに、PostgreSQL のデータベースにおけるLOCALEについて、
⇧ 上記サイト様がまとめて下さっておりました。
SQLでソートしたい値として、日本語があるような要件が必要とされる場合は、LOCALEとして「ja_JP.UTF8」を指定する感じになるんかね?
ちなみに、
- Linuxでは(バージョンとかディストリビューションで違いがあるかは知らない)デフォルトでは
ja_JP.UTF-8
がないようなのでPostgreSQLの設定だけ行っても起動時にエラーとなる。- ↑のDockerfileに書いたようにlocaledefで追加する必要がある
⇧ 上記サイト様によりますと、そもそも、サーバー自体(Linuxとか)が、対応していないこともあるそうな。
気になるのは、
- JIS X 0213
- 第1面
→JIS X 0208の非漢字,JIS第1,2,3水準漢字 - 第1面
→第2面には第4水準漢字
- 第1面
⇧ このあたりのソートにも対応してるのか?
一応、
⇧ 上記サイト様によりますと、漢字もソートの対象となっているような感じではあるのですが、ハッキリとは分からない。
とりあえす、CREATE DATABASEする際は、ENCODINGとしては、明示的にUTF-8にしておいた方が良そうな気はしますかね。
毎度モヤモヤ感が半端ない…
今回はこのへんで。