我正在使用 Postgresql v12。我创建了一个像这样的排序规则:
CREATE COLLATION ci (provider = icu, locale = 'tr_TR', deterministic = false);
Run Code Online (Sandbox Code Playgroud)
我在表中使用了该排序规则:
create table testtable1 (
id serial primary key,
name text COLLATE "ci"
);
Run Code Online (Sandbox Code Playgroud)
我插入了示例数据:
insert into testtable1 values(3,'abc');
Run Code Online (Sandbox Code Playgroud)
当我使用 查询该表时LIKE
,它返回以下错误:
select name from testtable1 WHERE name LIKE '%a%'
Run Code Online (Sandbox Code Playgroud)
错误:LIKE SQL 状态不支持非确定性排序规则:0A000
但我需要使用LIKE
. 有什么办法允许这样做吗?
collation unicode case-sensitive international-components-unicode postgresql-12
Postgres 10 获得了使用国际组件进行 Unicode (ICU)排序的能力,而不是依赖于主机操作系统的实现。请参阅Peter Eisentraut在 PostgreSQL 10 中使用 ICU 支持的更强大的排序规则。
那么在创建数据库时究竟如何指定 ICU 排序规则呢?
我确实在CREATE DATABASE
to use 中阅读了一个提示,template0
而不是template1
iftemplate1
可能是使用编码和整理而不是您想要的新数据库创建的。并且在使用时template0
,您需要启用数据连接以覆盖默认值。
我在 Postgres 10 doc page for Collation Support中读到:
und-x-icu(用于“未定义”)
ICU“根”整理。使用它来获得合理的与语言无关的排序顺序。
因此,und-x-icu
在建立包含多语言文本的新数据库时,这似乎是一个很好的使用价值。当已知某种语言专注于特定语言时,该SELECT
命令可以指定另一种排序规则,例如 German de-x-icu
。否则,回退到默认值und-x-icu
。
所以我尝试了以下 SQL 在 Postgres 10 Beta 2 中创建一个数据库。
CREATE DATABASE timepiece_
TEMPLATE 'template0'
ALLOW_CONNECTIONS TRUE
CONNECTION LIMIT -1
ENCODING 'UTF8'
LC_COLLATE 'und-x-icu'
LC_CTYPE 'und-x-icu'
;
Run Code Online (Sandbox Code Playgroud)
失败并出现错误:
[42809] …
postgresql collation postgresql-10 international-components-unicode
ICU 指定不同的LDML 整理设置。其中一些看起来很有趣,尤其是关于大小写和口音的那些,
- “忽略重音”:
strength=primary
- “忽略重音”但要考虑大小写:
strength=primary caseLevel=on
- “忽略大小写”:
strength=secondary
- “忽略标点符号”(完全):
strength=tertiary alternate=shifted
- “忽略标点符号”但区分标点符号:
strength=quaternary alternate=shifted
可能是更好的做事方法
您还可以在此处查看这些文档。PostgreSQL 10 ICU 整理支持是否可以使用这些 ICU 选项和设置?
CREATE COLLATION special (provider = icu, locale = 'en@strength=primary');
SELECT 'Å' LIKE 'A' COLLATE "special"; # returns false
Run Code Online (Sandbox Code Playgroud)
我也试过CLDR BCP47
从 ICU 54 开始,排序规则属性也可以通过语言环境关键字指定,使用旧的语言环境扩展语法 ("
el@colCaseFirst=upper
") 或语言标记语法 ("el-u-kf-upper")。关键字和值不区分大小写。请参阅LDML 归类规范、归类设置和列出有效归类关键字及其值的数据文件。(不支持已弃用的属性 kh/colHiraganaQuaternary 和 vt/variableTop。)
为此,这看起来是对的
CREATE COLLATION special (provider = icu, locale = 'en-ks-level1');
SELECT …
Run Code Online (Sandbox Code Playgroud) postgresql collation postgresql-10 international-components-unicode
我有这个查询:
SELECT * FROM table ORDER BY label ASC;
Run Code Online (Sandbox Code Playgroud)
由于标签不是英文的,它们没有按正确的顺序排序(以“ö”开头的标签不在底部/末尾)。
因此,我尝试:
SELECT * FROM table ORDER BY label COLLATE "sv-SE" ASC;
SELECT * FROM table ORDER BY label COLLATE "sv_SE" ASC;
Run Code Online (Sandbox Code Playgroud)
这些给出了关于那些不存在的排序规则的错误,这让我感到困惑。
经过一番搜索,我想出了这样做:
SELECT * FROM pg_collation;
Run Code Online (Sandbox Code Playgroud)
这表明它应该是:
sv-SE-x-icu
Run Code Online (Sandbox Code Playgroud)
当我使用该标识符时它起作用了,但是“-x-icu”的东西有什么用?那是怎么回事?我讨厌他们总是不得不弄乱标准的语言环境标识符,所以你永远不能只依赖标准的“language_location”格式。
postgresql collation unicode international-components-unicode