citext

citext

citext模块提供了一种大小写不敏感的字符串类型:citext。特别地,它在比较值时内部调用的是lower。除此之外,它的行为几乎与text完全相同。

基本原理

在UDB-TX中做大小写不敏感匹配的标准方法曾经是在比较值时使用lower函数,例如:

SELECT * FROM tab WHERE lower(col) = LOWER(?);

这工作得比较好,但是有一些缺点:

  • 它让你的 SQL 语句冗长,并且你必须总是要记住在列和查询值上使用lower

  • 它不会使用一个索引,除非你使用lower创建一个函数索引。

  • 如果你声明一个列为UNIQUEPRIMARY KEY,隐式生成的索引是大小写敏感的。因此,它对于大小写不敏感的搜索是没有用处的,并且它不会强制大小写不敏感的唯一性。

citext数据类型允许你在 SQL 查询中消除对lower的调用,并且允许一个主键是大小写无关的。就和text一样,citext是区域相关的,这意味着大写和小写字符的匹配依赖于数据库LC_CTYPE设置的规则。此外,这种行为和在查询中使用lower是一样的。但是因为它是由数据类型以透明的方式完成的,你不需要记住在你的查询中做任何特殊的事情。

如何使用它

这里是一个简单的用法示例:

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';

即使nick列被设置为larry而查询是LarrySELECT语句也将只返回一个元组。