是否有任何DBMS具有区分大小写和不区分重音的排序规则?


18

请注意,此问题与供应商/版本无关

在我看来,作为说英语的专家(打字员,作家),可以合理地期望单词使用正确的大小写,但不一定具有沿正确方向的正确口音:

当我和Chloe在香榭丽舍大街的饭店maitre d'hotel的tete-a-tete中沉思时,一边等待加尔肯(garcon)取回我炒过的墨西哥胡椒酱...

您就知道了。

因此,今天我想我希望搜索条件使用区分大小写但不区分变音的排序规则,但找不到一个。是否有充分的理由还是我的情况很少见?


这是我正在查看的一些文档示例(尽管认为与供应商/版本无关):

SQL Server排序规则名称(SQL Server 2008 R2)

Answers:


33

TL; DR

归类没有“与供应商无关”的视图,甚至也没有“版本无关”的东西,因为它们的实现(包括哪些方面可以变得不敏感以及它们的命名约定)是特定于供应商的,并且会随着时间而变化。

这是我发现的内容的摘要,详细信息在该行下面的较长部分中:

RDBMS        Naming-             Combinations    Case-Sensitive and
             convention          of options?     Accent-Insensitive support?
-------      ------------        -------------   -----
SQL Server   _CS, _AI, etc       Yes             Latin1_General_100_CS_AI

DB2          _E{x}, _S{y}, etc   Yes             CLDR181_EO_S1

PostgreSQL   locale: en_US       N/A             unaccent(), not via Collation

MySQL        _cs, maybe _ai      No              No: _cs implies _as & _ci implies _ai
                                                 Yes? Create your own Collation :-)

Oracle       only _CI & _AI      No              No: _AI always implies _CI

SAP ASE      arbitrary: turdict  N/A             No: "AI" always implies "CI"

Informix     locale.codepage     N/A             No: no "AI" via Collations

从图表中可以看到,七个RDBMS中的两个确实通过归类支持“ 区分大小写不区分重音”的操作,尽管它们具有不同的命名约定(以及其他一些功能差异)。

一个RDBMS(PostgreSQL)本身不支持这种组合,但是您仍然可以通过使用unaccent()附加功能去除重音来实现。

最后四个RDBMS,其中两个选项的命名约定相似,它们既不本地支持该组合,也没有一种无需编写自己的去除重音符号或变音符号的功能即可实现此目的的方法。MySQL允许创建您自己的归类,但是这要求您然后将其添加到源代码管理中并将其合并到测试和部署过程中,以便可以将其应用于所有环境中的所有服务器(但仍然是一个非常酷而灵活的选项) 。SAP ASE提到SAP 可以提供其他Unicode排序顺序,但是没有提及他们可能愿意提供的内容。

关于:

是否有充分的理由还是我的情况很少见?

我可以说,在研究此答案的过程中,我遇到了很多人希望对MySQL不区分大小写和区分重音的情况,但是很少有人问您想要的组合。


我希望搜索条件使用区分大小写但不区分变音的排序规则,但找不到。
...
此问题与供应商/版本无关

您搜索失败,因为基于归类规范查找RDBMS并没有任何意义。这不是排序规则的工作方式。而且,尽管您希望以与供应商无关的方式来处理此问题,但事实是,排序规则(至少是我们与之交互的部分)是非常特定于供应商的,并且并不总是适合您要搜索的方案。

字符串比较和排序非常复杂,执行这些规则的方式也不同。一种方法是让映射考虑一个或多个规则。因此,区分大小写和重音的敏感和不敏感的四个组合将等同于四个独立的映射。例如,您在该MSDN页面上看到了SQL Server排序规则名称。如果向下滚动,您会看到图表的左列是Sort Order ID。每个排序规则都有一个不同的ID:SQL_Latin1_General_Cp1_CI_AS= 52 while SQL_Latin1_General_Cp1_CS_AS= 51,即使唯一的区别在于区分大小写。

或者,它可以基于规则,例如Unicode通过Unicode排序算法(UCA)提供的功能。在这种方法中,默认情况下,每个字符都被赋予一个或多个权重。然后,每个区域性/区域设置都可以选择覆盖这些权重中的任何权重,删除规则或添加规则。该算法考虑到任何特定于语言环境的规则,然后有可能根据所选的任何选项(敏感度,进行区分大小写的排序等情况下首先出现)来操纵这些权重。这就是为什么进行Unicode排序要比非Unicode排序慢一些的原因之一。

要了解实际有多少选项(即实际的复杂性),请从ICU(Unicode国际组件)项目中查看此演示:

ICU整理演示

有8个不同的选项来指定,其中一些得到你所想的(例如归类名规范的多个元素表示CSCIASAI,等)。给定有多少种变化,使用每个组合都有其自己ID的映射文件方法将产生成千上万个文件。每当这些特定语言发生变化或发现错误时,其中许多文件将需要更新。这可能就是为什么SQL Server 2012中只有75种此类归类(即名称以开头的归类SQL_)的原因。因此,没有组合_CS_AI

以及为什么找不到基于UCA的归类的组合的原因?好的,SQL Server 2012中有3810个排序规则不以开头SQL_,因此共有3885个排序规则。该列表似乎太长,无法在网页上完整列举。但这并不能完全解释为什么您找不到其他供应商的这种组合。

除了已经提到的内容(即要实现的组合过多,还有要列出的实现)之外,您仍然需要应对特定于供应商的实现。含义:并非所有供应商都允许定制所有这些选项,并且首先没有针对归类的标准命名约定。另外,并非所有供应商都将排序选项视为归类的一部分:PostgreSQL归类是所选语言环境的默认排序,您需要使用ILIKE以获得不区分大小写的比较。请参阅下面的供应商特定信息。

SQL Server(微软)

您在这两个MSDN文档页面上看到的内容与@MartinSmith在对该问题的评论中提供的查询之间的区别(以下略作修订):

SELECT *
FROM   sys.fn_helpcollations()
WHERE  [name] LIKE '%[_]CS[_]AI%';

是,这两个MSDN页面专门指的是已过时的SQL Server排序规则,而作为该查询结果显示的排序规则(在SQL Server 2012,SP3和888中为888)是Windows排序规则。

从SQL Server 2000开始,不推荐使用较旧的SQL Server排序规则(在SQL Server能够使用Windows排序规则之前创建),并且不会使用新规则或功能进行更新。例如,从SQL Server 2012开始,添加了一组排序规则,以支持对补充字符(即,最初在UCS-2中定义的“基本” 65536个字符之外的其余UTF-16字符)的内置函数的正确处理。 )。这些较新的排序规则结束_SC(如在小号 upplementary Ç haracters)。

最好不要使用SQL Server排序规则-名称以SQL_。开头的排序规则。因此,您确实可以访问大量的排序规则,这些排序规则支持您要查找的选项的组合(例如,区分大小写和不区分重音)。只要有可用,最好也使用一端,_SC只要它具有您想要的所有其他选项即可。

尽管SQL Server确实使用了_CS_AI命名约定,但没有列出所有3810(自SQL Server 2012起)Windows排序规则。只有Windows排序规则名称页面列出了所有语言环境和版本,以及命名约定的工作原理,仅此而已。

SQL Server还支持切换宽度和假名灵敏度。

MySQL(由Oracle购买)

MySQL的版本5.7,文档指出它不支持_ai_as_ci,和_cs后缀(和_bin的完整性),但也指出:

对于未指定重音符号敏感性的非二进制排序规则名称,由大小写敏感性决定。也就是说,如果排序规则名称中不包含_ai_as,则_ci该名称包含_ai_cs而该名称包含_as

例如,latin1_general_ci不区分大小写(暗含重音),不区分大小写(暗含latin1_general_cs重音)

这当然意味着可以进行latin1_general_cs_ai归类。然而,MySQL的50年5月5日服务器,我有机会获得不具有多个后缀的排序规则,并且唯一的后缀我看到的是:_cs_ci,和_bin跨越198总排序规则。我使用了SHOW COLLATION命令将它们列出。

因此,尽管听起来MySQL使用了类似的命名约定(至少就这两个选项而言),但我找不到符合您要查找内容的Collat​​ion。但是,可能可以去除重音符号(和其他变音符号)并使用_cs排序规则来获取所需的内容(类似于在PostgreSQL中的操作方式-参见下文)。但是我不确定该选项,目前没有时间进一步研究。

,您可以创建自己的归类来完全执行您想要的操作。与其他RDBMS不同,MySQL似乎使添加自己的排序规则变得相当简单,在这种情况下,您可以完全控制每个字符的权重。有关更多详细信息,请参见将简单排序规则添加到8位字符集将UCA排序规则添加到Unicode字符集

有关MySQL如何处理不同类型的归类的更多信息,请参见其归类实现类型页面。

PostgreSQL的

PostgreSQL中的排序规则似乎不太灵活。您仅指定区域性/区域设置:en_USde_DE等等。有关详细信息,请参阅其文档页面以获取归类支持。因此,在默认情况下你得到的特定的文化覆盖,但排序规则,否则一切敏感(其中,顺便说一句,是一样的“二进制”排序)。

您可以使用ILIKE(第9.7.1节)来获得不区分大小写的字母,但是它们没有类似的重音符号运算符。但是,我发现它们确实具有不重音功能,可用于去除重音和其他变音标记。请注意,此功能是附加提供的模块,因此不一定要在要使用的任何特定PostgreSQL服务器中提供。最近链接的文档指出:

从源代码发行版进行构建时,除非您构建“世界”目标,否则不会自动构建这些组件

如果使用的是PostgreSQL的预打包版本,则通常将这些模块作为单独的子包提供,例如PostgreSQL的贡献。

请参阅该文档,以获取有关在没有该功能的情况下如何获得该功能的说明。

还可以在以下堆栈溢出答案中找到更多信息:

PostgreSQL是否支持“不区分重音”的排序规则?

DB2(IBM)

与Microsoft SQL Server相似,DB2具有两种类型的排序规则:

  • “系统”归类,使用以下格式指定:SYSTEM_{codepage}_[optional-territory]。这些不是很灵活,并且似乎不支持对大小写,重音或其他任何东西进行剪裁敏感性。您可以在此处找到支持的归类列表:支持的地区代码和代码页

  • 基于Unicode排序算法(UCA)的排序规则。这些确实支持大量的剪裁。请参阅其基于Unicode排序规则算法的排序规则页面,以获取有关如何配置行为,命名约定以及有效语言环境列表的详细信息。请注意,在表1中,第三行的示例(“案例级别”)以:

    将“案例级别”属性设置为“开”并将“强度”属性设置为主要级别将忽略重音,但不会忽略大小写。

    那正是您想要的。但是,其语法为: CLDR181_EO_S1。这就是为什么您的搜索未找到任何与DB2相关的原因。

甲骨文

Oracle 10g增加了对不区分重音的比较和排序的支持。然而:

  • 它们仅具有表示“不敏感”操作的选项:_CI_AI
  • 您一次只能指定其中一个选项
  • 不区分大小写的选项-- _CI仍然区分重音
  • 不区分重音的选项-- _AI“也始终不区分大小写。” (引自下面链接的文档)

请参阅其语言排序和字符串搜索文档页面,以获取更多详细信息和示例。

SAP ASE(以前为Sybase ASE,又名Sybase)

ASE支持每个区域设置/字符集的以下一种或多种敏感度组合:

  • 区分大小写,区分重音
  • 不区分大小写,区分重音
  • 不区分大小写,区分重音,优先顺序
  • 不区分大小写,不区分重音

您可以在区域设置,字符集和可用的排序顺序之间的关系中选择它们的“ 选择默认排序顺序”页面。而且,您可以在“ 归类名称和ID”页面上看到“归类”的完整列表。

它们的归类命名约定是任意的,因为它们都是4-8个字符,并尝试捕获语言环境名称或代码页以及某种排序感觉。例如:

altnoacc==“ CP 850替代–无重音”
rusdict==“俄语词典排序”
dynix==“汉语拼音排序”

他们的“ 选择默认Unicode排序顺序”页面上有一条注释,指出:

您可以使用目录中的外部文件添加排序顺序$/collate/Unicode。名称和排序规则ID存储在中syscharsets。可以在syscharsets设置默认Unicode排序顺序之前不必输入外部Unicode排序顺序的名称。
...
外部Unicode排序顺序由SAP提供。不要尝试创建外部Unicode排序顺序。

目前尚不清楚SAP是否会提供外部排序顺序以允许区分大小写不区分重音。也许有一天我会通过电子邮件向他们询问是否可以提出要求。

为了获得所需的灵敏度组合,您应该能够创建一个标量用户定义函数来去除重音符号和其他变音标记。

Informix(IBM购买)

Informix似乎基本上只支持归类的默认排序和比较行为。因此,归类只是语言环境和字符集。区分大小写是在数据库级别处理的,默认情况下,它们区分大小写。通过在语句中指定NLSCASE INSENSITIVE,可以将数据库(不是表,列,查询,甚至谓词)设置为不区分大小写CREATE DATABASE

虽然可以通过每个客户端连接覆盖数据库排序规则(语言环境和字符集),但似乎没有一种方法可以覆盖区分大小写的设置。而且,NLSCASE选择在名称中是有原因的“NLS”:它不仅影响NCHARNVARCHAR数据; CHAR并且VARCHAR始终区分大小写。

没有解决口音敏感性问题,也没有内置功能来去除口音/变音标记。

Informix排序规则的命名约定为:

<lang>_<country>.<code set>

哪里:

  • <lang> = 2个字母或3个字母的语言代码
  • <country> = 2个字母的国家或地区代码
  • <code set> =以以下三种等效方式之一指定的代码页:
    • 名称: 8859-1
    • IBM CCSID号的十进制值: 819
    • IBM CCSID号的十六进制值: 0333

因此,以下三个语言环境规范都引用完全相同的语言环境:

  • fr_fr.8859-1
  • fr_fr.819
  • fr_fr.0333

有关更多信息,请参见:


1
@onedaywhen抱歉造成误会。由于与该供应商无关的方面尚未完全清楚,因为该概念实际上并不存在,而Collat​​ions也不总是使用该命名约定。我已经收集了更多信息(用于另外3个RDBMS),并正在更新我的答案。
所罗门·鲁茨基

4
抱歉打错了,但我的意思是“颜色”,例如蓝色的大写字母和红色的重音……只是在开玩笑!这很容易是我收到的最好的答案。非常感谢:)
一天,2016年

@onedaywhen oooohhhh ...颜色...现在...懂了...很幸运,这很简单:只需使用该--color标志即可。但是,我认为这仅在使用JCL提交查询时才有效。;-)。或者,如果您想看到红色和蓝色,也许我的答案中使用的图像就足够了吗?但是,要谨记:非常感谢您的赞美😺。另外,我只是添加了SAP ASE的信息并进行了其他一些编辑,所以请查看修订历史以了解详细信息。
所罗门·鲁茨基

更新:Postgres 10获得了对ICU归类的支持。请参阅Peter Eisentraut的博客文章
罗勒·布尔克

@BasilBourque感谢您提到PG10。最后,该博客文章指出:“ ICU在该领域提供了许多功能,我们尚未通过PostgreSQL公开这些功能。不区分大小写的排序方式,不区分重音的排序方式和完全自定义归类的选项。对于将来的Pos​​tgreSQL版本中的用户。” 因此,在第一个/当前的实现中,它不会更改我的答案中的任何信息。如果将来的产品确实允许大小写和口音敏感度控制,我将使用该信息更新答案。PG的伟大第一步,尽管:-)。
所罗门·鲁兹基

-3

选项名称说明NLS_LANG当前的语言,地区和数据库字符集,由会话范围的全球化参数确定。NLS_LANGUAGE会话的当前语言。NLS_SORT排序或比较文本时使用的字符值序列。

要检查当前的NLS设置,请键入:

从v $ NLS_PARAMETERS中选择*;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.