PostgreSQL支持“重音不敏感”的排序规则吗?
在Microsoft SQL Server中,可以指定“重音不敏感”归类(对于数据库,表或列),这意味着它可能用于查询
SELECT * FROM users WHERE name LIKE 'Jo?o' 找到具有Joao名称的行。 我知道,可以使用unaccent_string contrib函数从PostgreSQL中的字符串剥离重音,但我想知道PostgreSQL是否支持这些“重音不敏感”的排序规则,所以上面的SELECT将工作。
我使用
unaccent module的 – 这是一个完全不同于你所链接的东西。
每个数据库安装一次: CREATE EXTENSION unaccent; 如果你得到一个错误,如:
在数据库服务器上安装contrib包,就像在这个相关的答案中所说的: > Error when creating unaccent extension on PostgreSQL 除此之外,它还提供了可以与您的示例(其中LIKE似乎不需要)一起使用的函数unaccent()。 SELECT * FROM users WHERE unaccent(name) = unaccent('Jo?o'); 指数 要为这种查询使用索引,请创建一个index on the expression.但是,Postgres仅接受索引的IMMUTABLE函数。如果一个函数可以为同一个输入返回不同的结果,那么索引可能会无声地断开。 unaccent()只有STABLE不是IMMUTABLE 不幸的是,unaccent()只是STABLE,而不是IMMUTABLE。根据this thread on pgsql-bugs,这是由于三个原因: >它取决于字典的行为。 Some tutorials在web上指示只是将函数的易变性改为IMMUTABLE。这种强力方法在某些情况下可能会中断。 其他人建议一个simple 有一个持续的争论是否使明确声明使用的字典的variant with two parameters IMMUTABLE。阅读here或here。 另一个选择是这个模块与一个IMMUTABLE 最好的 我提出一种方法,至少与其他解决方案一样有效,但更安全: CREATE OR REPLACE FUNCTION f_unaccent(text) RETURNS text AS $func$ SELECT public.unaccent('public.unaccent',$1) -- 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 users WHERE 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:
大胆强调我。现在我们得到: SELECT unaccent('? ? ? ? ?'); unaccent ---------- OE AE oe ae ss 模式匹配 对于具有任意模式的LIKE或ILIKE,将其与PostgreSQL 9.1或更高版本中的模块 CREATE INDEX users_unaccent_name_trgm_idx ON users USING gin (f_unaccent(name) gin_trgm_ops); GIN and GIST indexes are more expensive to maintain.此索引可用于以下查询: SELECT * FROM users WHERE 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” Trigram索引也支持简单的正则表达式??。和与ILIKE的不区分大小写模式匹配: > PostgreSQL accent + case insensitive search (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |