PostgreSQL COLLATE
PostgreSQLで日本語の文字列が入るカラムを指定した ORDER BY col_ja_text ASC で期待する並び順にならないということがあった table:table
id title
1 ほげふが2
2 ほげふが3
3 ほげふが1
いずれも末尾の数字はマルチバイト文字ではあるが、1,2,3の順序で表示されたい
開発者のマシンでは期待される結果となったが、AWS Aurora に作成した PostgreSQL のデータベースではソート順が期待と違っていた しらべる
PosgreSQL は照合順序のサポートがあり「照合順序機能は、ソート順番と列ごともしくは操作ごとのデータの文字区別の振る舞いを指定することを可能」にする
Aurora でデータベース作成時に特に指定がない場合にどの collation がデフォルトになるかの明記はドキュメントにはない
上記にあるように、パラメータは babelfishpg_tsql.server_collation_name で、デフォルト値は sql_latin1_general_cp1_ci_as となる
Babelfish はそもそも SQL Server データベースと PostgreSQL データベースの互換性をたもつための拡張だった
COLLATIONの変更をするという目的には合致しない
DB superuser で接続すればいまのデータベースがどの collation なのかは確認できる
code:collate.sql
SELECT datname, datcollate, datctype
FROM pg_database
WHERE datname = current_database();
datname | datcollate | datctype
--------------+------------+------------
mydb | en_US.utf8 | en_US.utf8
(1 row)
結果データベース作成時に指定するほかなさそう
なんとかする
なによりデータベース作成時に決定的であれば指定するのが一番良い
code:collate.bash
initdb --locale-provider=icu --icu-locale=ja
CREATE DATABASE のデフォルトの LC_COLLATE や LC_CTYPE が ja になる
テーブルやカラムに明示しなくても、日本語向けの並び順(自然な順)がデフォルトになる
今すぐアプリケーション側でどうにかするには ORDER BY SQL に COLLATE を指定するという方法がある
code:collate.sql
SELECT * FROM users ORDER BY name COLLATE "ja-JP-x-icu";
カラムに COLLATE を指定する方法もある
code:collate.sql
ALTER TABLE users
ALTER COLUMN name TYPE TEXT COLLATE "ja-JP-x-icu";