PostgreSQLのデータベースクラスタを作成する

久しぶりにロケールで悩んだのでメモ。

久しぶりにまっさらの環境でシステム開発することになった。まずは環境チェック。

$ psql
psql (15.8)
"help"でヘルプを表示します。
=> \l
                                       データベース一覧
   名前    |  所有者  | エンコーディング |  照合順序  | Ctype(変換演算子) | [省略] |     アクセス権限
-----------+----------+-------------+------------+----------------+--------+-------------------
 postgres  | postgres | UTF8        | ja_JP.utf8 | ja_JP.utf8     |        |
 template0 | postgres | UTF8        | ja_JP.utf8 | ja_JP.utf8     |        | =c/postgres [省略]
 template1 | postgres | UTF8        | ja_JP.utf8 | ja_JP.utf8     |        | =c/postgres [省略]
(3 行)

バージョンは15。
ロケールが設定されている。
ロケール設定していいん? 常識が変わった?

「PostgreSQL インストール」で検索するとびっくりするくらいロケールについての記述がない。やだ、"–no-locale"するのって時代遅れ?

データベースクラスタの作成もPostgreSQLのコマンドを素で使うんじゃなくラッパースクリプト経由で使うのが主流なの?

件のデータベースクラスタもpostgresql-setupで作成してた。

$ /usr/bin/postgresql-setup –initdb

postgresql-setupを読んでみたけどよくわからん。

デフォルトでOSの環境値からエンコーディングやロケールを取得してるらしいのと、変更は環境変数「PGSETUP_INITDB_OPTIONS」に"–encoding=UTF8 –no-locale"みたいに文字列を設定すればイケそうなのは見当がついた。

今回はオプションなしだからOSの「LANG=ja_JP.utf8」がロケールに設定されたみたい。

ロケールの功罪に関してはQiita:PostgreSQLにおけるロケールの影響調査を見つけた。すごい。丁寧。感謝。

ただ、この記事はちょっと古くて最終更新が2016/06/12だ。2016/06だとPostgreSQL9.5(PostgreSQL-Wikipadia)だから今はロケール大丈夫なのかもしれない。

で、何か最近のバージョンのロケールについて情報がないかとあちこち探していたら公式のマニュアルにありましたよ。灯台下暗し。

PostgreSQLでロケールを使用する際の欠点は実行速度です。 ロケールは文字の扱いを遅くし、さらにLIKEで通常のインデックスが使用されなくなります。この理由から、本当に必要な時のみロケールを使用してください。
PostgreSQL 15.4文書 - 24.1.2. 動作 より

公式が「必要な時のみロケールを使用してください」って言ってるので、これで安心してロケール無しでデータベースクラスタを作成できます。

結局、postgresql-setupは使わずに素のinitdbで作成しました。

$ initdb --encoding=UTF8 --no-locale
  :
  :
$ psql
psql (15.8)
"help"でヘルプを表示します。
=> \l
                                      データベース一覧
   名前    |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) | [省略] |     アクセス権限
-----------+----------+-------------+----------+----------------+--------+-------------------
 postgres  | postgres | UTF8        | C        | C              |        |
 template0 | postgres | UTF8        | C        | C              |        | =c/postgres [省略]
 template1 | postgres | UTF8        | C        | C              |        | =c/postgres [省略]
(3 行)

 

結論

*公式マニュアル「24.1.2. 動作」のページに「本当に必要な時のみロケールを使用してください」の文言がある間はロケール設定はしない。てか、普通にシステム作ってたらロケールが必要になることってないなー
PostgreSQL15, PostgreSQL16

*今でもデータベースクラスタの作成は素のinitdbが簡単確実。

$ initdb --encoding=UTF8 --no-locale