在microsoftsqlserver中,可以指定一个“不区分重音”的排序规则(对于数据库、表或列),这意味着对于类似
SELECT * FROM users WHERE name LIKE 'João'
找一排有 Joao
姓名。
我知道在postgresql中使用uncent\u string contrib函数可以去除字符串中的重音,但是我想知道postgresql是否支持这些“不区分重音”的排序规则,所以 SELECT
上面的话就行了。
在microsoftsqlserver中,可以指定一个“不区分重音”的排序规则(对于数据库、表或列),这意味着对于类似
SELECT * FROM users WHERE name LIKE 'João'
找一排有 Joao
姓名。
我知道在postgresql中使用uncent\u string contrib函数可以去除字符串中的重音,但是我想知道postgresql是否支持这些“不区分重音”的排序规则,所以 SELECT
上面的话就行了。
3条答案
按热度按时间chhqkbe11#
使用uncent模块来实现这一点-这与您正在链接的内容完全不同。
uncent是一个文本搜索字典,它可以从词素中删除重音(变音符号)。
每个数据库安装一次:
如果出现如下错误:
在数据库服务器上安装contrib包,如以下相关答案所示:
在postgresql上创建非关联扩展时出错
除此之外,它还提供
unaccent()
你可以用你的例子(其中LIKE
似乎不需要)。索引
若要对此类查询使用索引,请在表达式上创建索引。然而,postgres只接受
IMMUTABLE
索引函数。如果一个函数可以为同一个输入返回不同的结果,索引可能会自动中断。uncent()只稳定不不变
不幸的是,
unaccent()
只是STABLE
,不是IMMUTABLE
. 根据pgsql bug上的这个线程,这是由三个原因造成的:这取决于词典的行为。
这本词典没有硬连线。
因此,这也取决于电流
search_path
,很容易改变。网上的一些教程指示只需将函数更改为
IMMUTABLE
. 这种蛮力方法在某些情况下可以破坏。其他人则建议一个简单的方法
IMMUTABLE
Package 函数(就像我以前做的那样)。是否用两个参数来制作变型,目前仍有争论
IMMUTABLE
它显式声明使用的字典。读这里或这里。另一种选择是使用不可变的
unaccent()
musicbrainz提供的函数,在github上提供。我自己也没试过。我想我想出了一个更好的主意:现在最好
这种方法比其他解决方案更有效,也更安全。
创建
IMMUTABLE
sql Package 器函数使用硬连线的模式限定函数和字典执行双参数表单。因为嵌套一个非不变函数会禁用函数内联,所以它基于声明的c函数的副本(fake)
IMMUTABLE
也。它的唯一用途是在sql函数 Package 器中使用。不打算单独使用。复杂度是必需的,因为在c函数的声明中没有办法硬连接字典(sql Package 函数可以做到这一点,并允许函数内联和表达式索引。
放下
PARALLEL SAFE
来自postgres 9.5或更高版本的两个函数。public
作为安装扩展的架构(public
是默认值)。显式类型声明(
regdictionary
)防止恶意用户使用函数的重载变体进行假设攻击。以前,我提倡使用基于
STABLE
功能unaccent()
随未安装模块一起提供。禁用了函数内联。这个版本的执行速度比我之前在这里使用的简单 Package 函数快十倍。这已经是第一个版本的两倍了
SET search_path = public, pg_temp
直到我发现字典也可以是模式限定的。不过(postgres 12)从文档中看不太明显。如果您缺乏创建c函数所需的特权,那么您将回到第二个最佳实现:一个
IMMUTABLE
函数 Package 器STABLE
unaccent()
模块提供的功能:最后,使用表达式索引来快速查询:
记住,在对函数或字典进行任何更改之后,重新创建涉及此函数的索引,就像不重新创建索引的就地主要版本升级一样。最近的主要版本都有
unaccent
模块。调整查询以匹配索引(以便查询规划器使用它):
您不需要正确表达式中的函数。在这里,您还可以提供无注解的字符串,如
'Joao'
直接。使用表达式索引时,faster函数不会转换为更快的查询。它对预先计算的值进行操作,并且已经非常快了。但是索引维护和查询不使用索引的好处。
postgres 10.3/9.6.8等加强了客户端程序的安全性。在任何索引中使用时,都需要对函数和字典名进行模式限定。请参见:
“文本搜索词典”uncent“不存在”词条在postgres日志中,假设在自动分析期间
连字
在postgres 9.5或更老的连字中,如'œ' 或'ß' 必须手动展开(如果需要),因为
unaccent()
始终替换单个字母:您会喜欢postgres 9.6中的uncent更新:
延伸
contrib/unaccent
的标准unaccent.rules
文件来处理unicode已知的所有音调符号,并正确展开连字(thomas munro,lé奥纳德·贝内德蒂)我的。现在我们得到:
模式匹配
为了
LIKE
或者ILIKE
对于任意模式,请将其与模块相结合pg_trgm
在postgresql 9.1或更高版本中。创建一个三角图(通常更可取)或gist表达式索引。琴酒示例:可用于以下查询:
gin和gist索引的维护成本高于普通btree:
gist和gin指数之间的差异
对于左锚定模式有更简单的解决方案。有关模式匹配和性能的详细信息:
postgresql中like、similor或正则表达式的模式匹配
pg_trgm
还为“相似性”提供了有用的运算符(%
)和“距离”(<->
).三角形索引还支持简单的正则表达式
~
和不区分大小写的模式匹配ILIKE
:postgresql重音+不区分大小写搜索
x6492ojm2#
不,postgresql不支持这种排序规则
postgresql不支持这样的排序规则(不区分重音与否),因为除非二进制相等,否则任何比较都不能返回相等。这是因为在内部,它会给哈希索引之类的东西带来很多复杂性。因此,严格意义上的排序只影响顺序,而不影响相等。
变通办法
全文搜索词典,不包括词素。
对于fts,您可以使用
unaccent
,你可以用函数索引,
现在可以非常简单地查询它
另请参见
在字段上创建不区分大小写和重音/音调符号的搜索
孤零零的。
这个
unaccent
模块也可以自己使用,而无需fts集成,为此,请查看erwin的答案aoyhnmkz3#
我很确定postgresql依赖于底层操作系统进行排序。它确实支持创建新的排序规则和自定义排序规则。不过,我不确定你要做多少工作(可能很多。)