Postgresql 中文操作指南
F.10. citext — a case-insensitive character string type #
citext 模块提供了一个不区分大小写的字符串类型 citext。从本质上来说,在比较值时,它在内部调用 lower。否则,它几乎完全像 text 一样运行。
Tip
考虑使用 nondeterministic collations (参见 Section 24.2.2.4)代替此模块。它们可用于大小写不敏感比较、重音不敏感比较和其他组合,并且可以正确处理更多 Unicode 特殊情况。
此模块被认为是“受信任的”,也就是说,它可以由在当前数据库上具有 CREATE 权限的非超级用户安装。
F.10.1. Rationale #
在 PostgreSQL 中执行不区分大小写匹配的标准方法是在比较值时使用 lower 函数,例如
SELECT * FROM tab WHERE lower(col) = LOWER(?);
这相当不错,但有若干缺点:
citext 数据类型允许您在 SQL 查询中消除对 lower 的调用,并且允许将主键设为不区分大小写。citext 是对区域设置敏感的,就像 text 一样,这意味着匹配大写字符和小写字符取决于数据库 LC_CTYPE 设置的规则。同样,此行为与在查询中使用 lower 完全相同。但由于数据类型以透明的方式完成此操作,因此您不必在查询中记住做任何特殊的事情。
F.10.2. How to Use It #
下面是一个简单的使用示例:
CREATE TABLE users (
nick CITEXT PRIMARY KEY,
pass TEXT NOT NULL
);
INSERT INTO users VALUES ( 'larry', sha256(random()::text::bytea) );
INSERT INTO users VALUES ( 'Tom', sha256(random()::text::bytea) );
INSERT INTO users VALUES ( 'Damian', sha256(random()::text::bytea) );
INSERT INTO users VALUES ( 'NEAL', sha256(random()::text::bytea) );
INSERT INTO users VALUES ( 'Bjørn', sha256(random()::text::bytea) );
SELECT * FROM users WHERE nick = 'Larry';
SELECT 语句将返回一个元组,即使 nick 列已设为 larry 且查询为 Larry。
F.10.3. String Comparison Behavior #
citext 通过将每个字符串转换为小写(就如同调用了 lower)来执行比较,然后正常比较结果。因此,例如,如果 lower 会对它们产生相同的结果,那么两个字符串将被视为相等。
为了尽可能模拟不区分大小写的归类,有大量字符串处理运算符和函数的 citext 专用版本。因此,例如,当应用于 citext 时,正则表达式运算符 ~ 和 ~* 会表现出相同行为:它们都匹配不区分大小写。!~ 和 !~* 也是如此,还有 LIKE 运算符 ~~ 和 ~~*,以及 !~~ 和 !~~*。如果您想匹配区分大小写,则可以将运算符的参数强制转换为 text。
同样,如果其参数为 citext,则所有以下函数的功能都执行不区分大小写的匹配:
对于正则表达式函数,如果希望进行区分大小写的匹配,可以指定“c”标志来强制进行区分大小写的匹配。否则,如果你希望对这些函数中的一个进行区分大小写的处理,必须在使用这些函数之前将其强制转换为 text。
F.10.4. Limitations #
F.10.5. Author #
David E. Wheeler < link:mailto:david@kineticode.com[david@kineticode.com]>
受到唐纳德·弗雷泽的最初 citext 模块的启发。