## F.8.citext [F.8.1.根本原因](citext.html#id-1.11.7.17.6)[F.8.2.如何使用它](citext.html#id-1.11.7.17.7)[F.8.3.字符串比较行为](citext.html#id-1.11.7.17.8)[F.8.4.局限性](citext.html#id-1.11.7.17.9)[F.8.5.著者](citext.html#id-1.11.7.17.10) [](<>) 这个`citext`模块提供不区分大小写的字符串类型,`citext`.本质上,它在内部调用`降低`比较数值时。否则,它的行为几乎与`文本`. ### 提示 考虑使用*非确定性排序*(见[第24.2.2.4节](collation.html#COLLATION-NONDETERMINISTIC))而不是这个模块。它们可以用于不区分大小写的比较、不区分重音的比较和其他组合,并且可以正确处理更多的Unicode特殊情况。 该模块被认为是“受信任的”,也就是说,它可以由拥有`创造`当前数据库的权限。 ### F.8.1.理由 在PostgreSQL中进行不区分大小写匹配的标准方法是使用`降低`例如,在比较值时使用函数 ``` SELECT * FROM tab WHERE lower(col) = LOWER(?); ``` 这项工作相当不错,但也有一些缺点: - 这会使SQL语句变得冗长,而且您必须始终记住使用`降低`在列和查询值上。 - 它不会使用索引,除非使用`降低`. - 如果将列声明为`唯一的`或`主键`,隐式生成的索引区分大小写。因此,它对于不区分大小写的搜索是无用的,而且它不会在不区分大小写的情况下强制唯一性。 这个`citext`数据类型允许您消除对`降低`并允许主键不区分大小写。`citext`是区域识别的,就像`文本`,这意味着大小写字符的匹配取决于数据库`LC_CTYPE`背景同样,这种行为与使用`降低`在查询中。但是因为它是通过数据类型透明地完成的,所以您不必记住在查询中执行任何特殊操作。 ### F.8.2.如何使用它 下面是一个简单的用法示例: ``` 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'; ``` 这个`选择`语句将返回一个元组,即使`刻痕`列被设置为`拉里`这个问题是为了`拉里`. ### F.8.3.字符串比较行为 `citext`通过将每个字符串转换为小写来执行比较(就像`降低`然后正常比较结果。因此,例如,如果`降低`将为他们产生相同的结果。 为了尽可能地模拟不区分大小写的排序规则,有`citext`-一些字符串处理运算符和函数的特定版本。例如,正则表达式操作符`~`和`~*`在应用于时表现出相同的行为`citext`例句他们两人都在毫无意识地配合情况。同样的道理也适用于中国`!~`和`!~*`,以及`喜欢`操作员`~~`和`~~*`和`!~~`和`!~~*`.如果您希望区分大小写,可以将运算符的参数转换为`文本`. 类似地,如果以下所有函数的参数为`citext`: - `regexp_match()` - `regexp_matches()` - `regexp_replace()` - `regexp_拆分为_数组()` - `regexp_split_to_table()` - `替换()` - `拆分部分()` - `strpos()` - `翻译()` 对于regexp函数,如果希望区分大小写匹配,可以指定“c”标志以强制区分大小写匹配。否则,你必须投出`文本`如果您想要区分大小写的行为,请在使用其中一个函数之前。 ### F.8.4.局限性 - `citext`的箱子折叠行为取决于`LC_CTYPE`数据库的设置。因此,在创建数据库时,将确定它如何比较值。在Unicode标准定义的术语中,它并不是真正不区分大小写的。实际上,这意味着,只要你对自己的排序感到满意,你就应该对自己的排序感到满意`citext`这是我的比较。但是,如果数据库中存储了不同语言的数据,一种语言的用户可能会发现,如果排序规则是针对另一种语言的,那么他们的查询结果可能与预期不符。 - 从PostgreSQL 9.1开始,您可以附加`整理`规范`citext`列或数据值。目前,`citext`运营商将遵守非违约条款`整理`在比较大小写折叠字符串时使用了规范,但对小写的初始折叠总是根据数据库的`LC_CTYPE`设置(也就是说`核对“默认值”`(已给出)。这可能会在未来的版本中更改,以便两个步骤都遵循输入`整理`规格 - `citext`效率不如`文本`因为运算符函数和B-树比较函数必须复制数据,并将其转换为小写进行比较。而且,只有`文本`可以支持B树重复数据消除。然而`citext`比使用`降低`以获得不区分大小写的匹配。 - `citext`如果你需要数据在某些情况下区分大小写,而在其他情况下不区分大小写,这并没有多大帮助。标准答案是使用`文本`键入并手动使用`降低`当您需要不敏感地比较大小写时,可以使用函数;如果不经常需要进行不区分大小写的比较,这种方法就可以了。如果大多数情况下需要不区分大小写的行为,并且不区分大小写,请考虑将数据存储为`citext`并明确地将该专栏`文本`当你需要区分大小写的比较时。在任何一种情况下,如果希望两种类型的搜索都快速,都需要两个索引。 - 包含`citext`操作员必须处于当前状态`搜索路径`(通常`平民的`); 如果不是,则正常情况下区分大小写`文本`将调用运算符。 - 用于比较的下套管串方法不能正确处理某些Unicode特殊情况,例如,当一个大写字母有两个小写字母等价物时。Unicode区别于*案例映射*和*箱子折叠*因为这个原因。使用不确定的排序规则,而不是`citext`正确处理这个问题。 ### F.8.5.作者 大卫·E·惠勒`<[david@kineticode.com](邮寄至:david@kineticode.com)>` 灵感来源于原作`citext`唐纳德·弗雷泽的模块。