PostgreSQL支持“重音不敏感”的排序规则吗?

PostgreSQL支持“重音不敏感”的排序规则吗?,第1张

概述在Microsoft SQL Server中,可以指定“重音不敏感”归类(对于数据库,表或列),这意味着它可能用于查询 SELECT * FROM users WHERE name LIKE 'João' 找到具有Joao名称的行。 我知道,可以使用unaccent_string contrib函数从PostgreSQL中的字符串剥离重音,但我想知道PostgreSQL是否支持这些“重音不敏感”的 在Microsoft sql Server中,可以指定“重音不敏感”归类(对于数据库,表或列),这意味着它可能用于查询
SELECT * FROM users WHERE name liKE 'João'

找到具有Joao名称的行。

我知道,可以使用unaccent_string contrib函数从Postgresql中的字符串剥离重音,但我想知道Postgresql是否支持这些“重音不敏感”的排序规则,所以上面的SELECT将工作。

我使用 unaccent module的 – 这是一个完全不同于你所链接的东西。

unaccent is a text search dictionary that removes accents (diacritic
signs) from lexemes.

每个数据库安装一次:

CREATE EXTENSION unaccent;

如果你得到一个错误,如:

ERROR: Could not open extension control file
“/usr/share/postgresql/9.x/extension/unaccent.control”: No such file
or directory

在数据库服务器上安装contrib包,就像在这个相关的答案中所说的:

> Error when creating unaccent extension on PostgreSQL

除此之外,它还提供了可以与您的示例(其中liKE似乎不需要)一起使用的函数unaccent()。

SELECT *FROM   usersWHERE  unaccent(name) = unaccent('João');

指数

要为这种查询使用索引,请创建一个index on the expression.但是,Postgres仅接受索引的IMMUtable函数。如果一个函数可以为同一个输入返回不同的结果,那么索引可能会无声地断开。

unaccent()只有Stable不是IMMUtable

不幸的是,unaccent()只是Stable,而不是IMMUtable。根据this thread on pgsql-bugs,这是由于三个原因:

>它取决于字典的行为。
>没有到这个字典的硬接线连接。
>因此它也取决于当前的search_path,它可以很容易改变。

Some tutorials在web上指示只是将函数的易变性改为IMMUtable。这种强力方法在某些情况下可能会中断。

其他人建议一个simple IMMUTABLE wrapper function – 像我自己在过去。

有一个持续的争论是否使明确声明使用的字典的variant with two parameters IMMUtable。阅读here或here。

另一个选择是这个模块与一个IMMUTABLE unaccent() function by Musicbrainz,提供Github。没有自己测试。我想我已经提出了一个更好的主意:

最好的

我提出一种方法,至少与其他解决方案一样有效,但更安全:
创建一个包含两个参数形式的包装器函数,并为函数和字典“硬连线”模式:

CREATE OR REPLACE FUNCTION f_unaccent(text)  RETURNS text AS$func$SELECT public.unaccent('public.unaccent',)  -- schema-qualify function and dictionary$func$  LANGUAGE sql IMMUtable;

public是您安装扩展的模式(public是默认值)。

更新02.2016:以前,我添加了SET search_path = public,pg_temp到函数 – 直到我发现字典也可以是模式限定的,which is currently not documented.这个版本有点更短,是我在pg上的测试的两倍9.5并允许 function inlining。

你可以在这个IMMUtable函数上建立一个expression index:

CREATE INDEX users_unaccent_name_IDx ON users(f_unaccent(name));

调整您的查询以使用索引:

SELECT *FROM   usersWHERE  f_unaccent(name) = f_unaccent('João');

你不需要在正确的表达式中的函数。你可以直接提供不重要的字符串,如“Joao”。

连字

在Postgres 9.5或更高版本中,我们需要手动(如果我们需要)展开连字,如“Œ”或“ß”,因为unaccent()总是替换一个字母:

SELECT unaccent('Œ Æ œ æ ß');unaccent----------E A e a S

你会爱上this update to unaccent在Postgres 9.6:

Extend contrib/unaccent‘s standard unaccent.rules file to handle all
diacritics kNown to Unicode,and expand ligatures correctly (Thomas
Munro,Léonard Benedetti)

大胆强调我。现在我们得到:

SELECT unaccent('Œ Æ œ æ ß');unaccent----------OE AE oe ae ss

模式匹配

对于具有任意模式的liKE或IliKE,将其与Postgresql 9.1或更高版本中的模块pg_tgrm组合。创建GIN(优选)或GIST表达式索引。 GIN的示例:

CREATE INDEX users_unaccent_name_trgm_IDx ON usersUSING gin (f_unaccent(name) gin_trgm_ops);

GIN and GIST indexes are more expensive to maintain.此索引可用于以下查询:

SELECT *FROM   usersWHERE  f_unaccent(name) liKE ('%' || f_unaccent('João') || '%');

对于刚刚左边锚定的模式有更简单的解决方案。更多关于模式匹配和性能:

> Pattern matching with LIKE,SIMILAR TO or regular expressions in PostgreSQL

pg_tgrm还提供了useful operators for “similarity” % and “distance” <->

Trigram索引也支持简单的正则表达式〜〜。和与IliKE的不区分大小写模式匹配:

> PostgreSQL accent + case insensitive search

总结

以上是内存溢出为你收集整理的PostgreSQL支持“重音不敏感”的排序规则吗?全部内容,希望文章能够帮你解决PostgreSQL支持“重音不敏感”的排序规则吗?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1172634.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存