Algum DBMS possui um agrupamento que faz distinção entre maiúsculas e minúsculas e sem distinção de sotaque?

18

Observe que esta pergunta é independente do fornecedor / versão

Parece-me que, como um falante (datilógrafo, escritor) de inglês, é razoável esperar que as palavras sejam colocadas em maiúsculas e minúsculas, mas não necessariamente com os sotaques corretos na direção certa:

enquanto eu pensava em um tete-a-tete com Chloe, o maitre d'hotel no restaurante Champs-Elysees, enquanto esperava a garcon buscar meu patê de jalapeno refogado ...

Você entendeu a ideia.

Então, hoje eu pensei que queria uma condição de pesquisa para usar um agrupamento que diferenciava maiúsculas de minúsculas, mas sem distinção de sotaque, mas não consegui encontrar um. Existe uma boa razão para isso ou o meu é apenas um caso de uso raro?


Aqui está um exemplo de alguma documentação que eu estava olhando (apesar de pensar em fornecedor / versão independente):

Nome do agrupamento do SQL Server (SQL Server 2008 R2)

um dia quando
fonte

Respostas:

33

TL; DR

Não existe uma visão "independente do fornecedor" dos agrupamentos, nem mesmo "independente da versão", pois suas implementações - incluindo quais aspectos podem ser tornados insensíveis e suas convenções de nomenclatura - são específicas do fornecedor e mudam com o tempo. .

Aqui está um resumo do que encontrei e os detalhes estão na seção mais longa abaixo da linha:

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

Como você pode ver no gráfico, dois dos sete RDBMSs fazer suporte nativamente "Case-sensíveis e operações Accent-insensíveis" via agrupamentos, embora eles têm diferentes convenções de nomenclatura (e várias outras diferenças funcionais).

Um RDBMS - PostgreSQL - não suporta nativamente essa combinação, mas você ainda pode obtê-lo removendo os acentos com a unaccent()função de complemento.

Os últimos quatro RDBMSs, dois dos quais possuem uma convenção de nomenclatura semelhante para as opções, nem suportam nativamente essa combinação nem parecem existir meios para realizar isso sem escrever sua própria função para remover os acentos / sinais diacríticos. O MySQL permite criar seus próprios agrupamentos, mas isso exige que você o adicione ao controle de origem e o incorpore ao seu processo de teste e implantação, para que possa ser aplicado a todos os servidores em todos os ambientes (mas ainda uma opção muito interessante e flexível) . O SAP ASE menciona que a SAP pode fornecer pedidos adicionais de classificação Unicode, mas nenhuma menção ao que eles podem estar dispostos a fornecer.

Com relação a:

Existe uma boa razão para isso ou o meu é apenas um caso de uso raro?

Posso dizer que, ao fazer a pesquisa para esta resposta, deparei-me com muitas instâncias de pessoas querendo maiúsculas e minúsculas para o MySQL, mas poucas, se houver, solicitando a combinação desejada.


Eu queria que uma condição de pesquisa usasse um agrupamento com distinção entre maiúsculas e minúsculas, mas sem distinção de sotaque, mas não consegui encontrar um.
...
esta questão é independente de versão / fornecedor

Você não teve êxito em sua pesquisa porque não faz sentido procurar um RDBMS com base em uma especificação de Collation. Não é assim que os Collations funcionam. E enquanto você deseja abordar isso como independente do fornecedor, a realidade é que os agrupamentos - pelo menos a parte com a qual interagimos - são muito específicos do fornecedor e nem sempre se encaixam no esquema em que você estava pesquisando .

A comparação e classificação de cadeias são altamente complexas e existem diferentes maneiras de executar essas regras. Um método é ter mapeamentos que levem em conta uma ou mais regras. Portanto, as quatro combinações de sensível e insensível a maiúsculas e minúsculas equivaleriam a quatro mapeamentos separados. Por exemplo, você viu isso na página do MSDN para o nome do agrupamento do SQL Server . Se você rolar para baixo, verá que a coluna esquerda do gráfico é a Sort Order ID. Cada agrupamento tem um ID diferente: SQL_Latin1_General_Cp1_CI_AS= 52 enquanto SQL_Latin1_General_Cp1_CS_AS= 51, mesmo que a única diferença esteja na distinção entre maiúsculas e minúsculas.

Ou pode ser baseado em regras, como o que o Unicode oferece por meio do Algoritmo de Collation Unicode (UCA). Nesta abordagem, cada caractere recebe, por padrão, um ou mais pesos. Em seguida, cada cultura / localidade tem a opção de substituir qualquer um desses pesos, remover regras ou adicionar regras. O algoritmo leva em consideração quaisquer regras específicas do código do idioma e, em seguida, manipula potencialmente esses pesos com base nas opções escolhidas (sensibilidade, caso que ocorre primeiro ao fazer classificações com distinção entre maiúsculas e minúsculas, etc.). Essa é uma das razões pelas quais a classificação Unicode é um pouco mais lenta que a classificação não Unicode.

Para ter uma idéia de quantas opções realmente existem (por exemplo, a complexidade real), confira esta demonstração no projeto ICU (International Components for Unicode):

Demonstração de agrupamento na UTI

Há 8 opções separadas para especificar, e alguns deles se representada em vários elementos da especificação nome de agrupamento que você está pensando em (por exemplo CS, CI, AS, AI, etc). Dadas as variações, o uso da abordagem de arquivo de mapeamento em que cada combinação tem seu próprio ID resultaria em milhares de arquivos. Muitos desses arquivos precisariam ser atualizados sempre que houver alterações nesses idiomas específicos ou quando forem encontrados erros. Provavelmente, é por isso que existem apenas 75 desses tipos de agrupamentos no SQL Server 2012 (ou seja, aqueles com nomes começando SQL_). Portanto, nenhuma combinação para _CS_AI.

E a razão pela qual você não conseguiu encontrar essa combinação para os agrupamentos baseados em UCA? Bem, existem 3810 Collations no SQL Server 2012 que não começam SQL_, portanto, 3885 Collations no total. Essa lista parece ser muito longa para ser totalmente enumerada em uma página da web. Mas isso não explica completamente por que você não encontrou essa combinação para outros fornecedores.

Além do que já foi mencionado (ou seja, muitas combinações para implementar e muitas implementações para listar), você ainda precisa lidar com implementações específicas do fornecedor. Significado: nem todos os fornecedores permitem personalizar todas essas opções e, em primeiro lugar, não há convenção de nomenclatura padrão para agrupamentos. Além disso, nem todos os fornecedores veem as opções de classificação como parte do agrupamento: os agrupamentos do PostgreSQL são pedidos padrão para o local escolhido, e você precisa usar ILIKEpara obter uma comparação que não diferencia maiúsculas de minúsculas. Veja abaixo as informações específicas do fornecedor.

SQL Server (Microsoft)

A distinção entre o que você vê nessas duas páginas de documentação do MSDN e a consulta fornecida pelo @MartinSmith em um comentário sobre a pergunta (ligeiramente revisada abaixo):

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

é que essas duas páginas do MSDN estão se referindo especificamente aos agrupamentos do SQL Server muito preteridos, enquanto os agrupamentos que aparecem como resultado dessa consulta (888 deles no SQL Server 2012, SP3) são agrupamentos do Windows.

A partir do SQL Server 2000, os agrupamentos mais antigos do SQL Server (criados antes do SQL Server poderem acessar os agrupamentos do Windows) foram preteridos e não estão sendo atualizados com novas regras ou funcionalidades. Por exemplo, a partir do SQL Server 2012, foi adicionado um conjunto de agrupamentos que suporta o manuseio adequado das funções internas para caracteres suplementares (ou seja, os caracteres UTF-16 restantes além dos 65.536 caracteres "base" inicialmente definidos no UCS-2 ) Estes agrupamentos mais recentes terminam em _SC(como em S upplementary C haracters).

É melhor não usar os agrupamentos do SQL Server - aqueles com nomes que começam com SQL_. Portanto, você tem acesso a muitos agrupamentos que suportam a combinação de opções que procura (por exemplo, com distinção entre maiúsculas e minúsculas e sem sotaque). Sempre que disponível, também é melhor usar uma extremidade _SC, desde que ela tenha todas as outras opções desejadas.

Embora o SQL Server use a _CS_AIconvenção de nomenclatura, não há uma lista de todos os 3810 (no SQL Server 2012) agrupamentos do Windows. Existe apenas a página Nome do agrupamento do Windows que lista todos os códigos de idioma e versões e como a convenção de nomes funciona, mas é isso.

O SQL Server também oferece suporte para alternar a sensibilidade de largura e Kana.

MySQL (comprado pela Oracle)

O MySQL versão 5.7, documentação estados que suporta o _ai, _as, _ci, e _cssufixos (e _binpara ser completo), mas também afirma:

Para nomes de agrupamento não binários que não especificam a sensibilidade ao acento, é determinado pela distinção entre maiúsculas e minúsculas. Ou seja, se um nome de agrupamento não contiver _aiou _as, _cino nome implica _aie _csno nome implica _as.

Por exemplo, latin1_general_cifaz distinção entre maiúsculas e minúsculas (e sem sotaque, implicitamente), latin1_general_csdiferencia maiúsculas de minúsculas (e com sotaque, implicitamente)

Isso certamente implica que é possível ter um latin1_general_cs_aiagrupamento. No entanto, o servidor MySQL 5.5.50 que eu tenho acesso a não tem nenhum agrupamentos com mais de um sufixo, e a única sufixos que vejo são: _cs, _cie _binem toda 198 agrupamentos totais. Eu usei o comando SHOW COLLATION para listá-los.

Portanto, embora pareça que o MySQL use uma convenção de nomenclatura semelhante (pelo menos no que diz respeito a essas duas opções), não consigo encontrar um agrupamento correspondente ao que você está procurando. No entanto, pode ser possível remover os acentos (e outras marcas diacríticas) e usar um _csagrupamento para obter o que você deseja (semelhante a como você faria no PostgreSQL - veja abaixo). Mas não tenho certeza dessa opção e não tenho tempo no momento para pesquisar mais.

OU , você pode criar seu próprio agrupamento para fazer exatamente o que deseja. Diferente dos outros RDBMSs, o MySQL parece simplificar a adição de seus próprios agrupamentos, caso em que você tem total controle sobre a ponderação de cada caractere. Consulte Adicionando um agrupamento simples a um conjunto de caracteres de 8 bits e Adicionando um agrupamento UCA a um conjunto de caracteres Unicode para obter mais detalhes.

Para obter mais informações sobre como o MySQL lida com diferentes tipos de agrupamentos, consulte a página Tipos de implementação de agrupamento .

PostgreSQL

Os agrupamentos no PostgreSQL parecem ser muito menos flexíveis. Você especifica apenas a cultura / locale: en_US, de_DE, etc. Por favor, veja sua página de documentação para Suporte de agrupamento para mais detalhes. Portanto, por padrão, você recebe as substituições específicas da cultura, mas os agrupamentos são sensíveis a tudo (que, a propósito, não é o mesmo que um agrupamento "binário").

Você pode usar o ILIKE (seção 9.7.1) para obter distinção entre maiúsculas e minúsculas, mas eles não têm um operador semelhante para sensibilidade ao sotaque. No entanto, descobri que eles têm uma função não - acentuada que pode ser usada para remover acentos e outras marcas diacríticas. Observe que esta função é um módulo fornecido adicional e, portanto, não está necessariamente presente em nenhum servidor PostgreSQL específico para uso. A documentação vinculada mais recentemente declara:

Ao construir a partir da distribuição de origem, esses componentes não são construídos automaticamente, a menos que você construa o destino "mundo"
...
Se você estiver usando uma versão pré-empacotada do PostgreSQL, esses módulos normalmente serão disponibilizados como um subpacote separado, como postgresql-contrib.

Consulte a documentação para obter instruções sobre como obter essa função, se você não a possui e deseja.

Mais informações também podem ser encontradas na seguinte resposta de estouro de pilha:

O PostgreSQL suporta agrupamentos que não sejam sensíveis ao sotaque?

DB2 (IBM)

Semelhante ao Microsoft SQL Server, o DB2 possui dois tipos de agrupamentos:

  • Collations "sistema", que são especificados usando o seguinte formato: SYSTEM_{codepage}_[optional-territory]. Elas não são muito flexíveis e não parecem suportar a sensibilidade de adaptação a maiúsculas, sotaques ou qualquer coisa. Você pode encontrar a lista de agrupamentos suportados aqui: Códigos de território e páginas de códigos suportados

  • Agrupamentos baseados em Algoritmo de Collation Unicode (UCA). Estes suportam bastante alfaiataria. Consulte a página de agrupamentos baseada no algoritmo de agrupamento Unicode para obter detalhes sobre como configurar o comportamento, a convenção de nomenclatura e a lista de códigos de idioma válidos. Observe que, na Tabela 1, o exemplo na terceira linha ("Nível do caso") começa com:

    Definir o atributo Nível do caso como ativado e o atributo Força como nível primário ignorará o acento, mas não o caso.

    Isso é exatamente o que você estava procurando. Mas, a sintaxe para isto é: CLDR181_EO_S1. E é por isso que sua pesquisa não encontrou nada relacionado ao DB2.

Oráculo

O Oracle 10g adicionou suporte para fazer comparações e classificação sem distinção de sotaque. Contudo:

  • eles têm apenas as opções para denotar operações "insensíveis": _CIe_AI
  • você pode especificar apenas uma dessas opções por vez
  • a opção que não diferencia maiúsculas de minúsculas - _CI- ainda é sensível ao sotaque
  • a opção sem distinção de sotaque - _AI- "também é sempre sem distinção entre maiúsculas e minúsculas". (citado em sua documentação, que está vinculada abaixo)

Consulte a página de documentação Classificação linguística e Pesquisa de cadeias para obter mais detalhes e exemplos.

SAP ASE (anteriormente Sybase ASE, também conhecido como Sybase)

O ASE suporta uma ou mais das seguintes combinações de sensibilidades por cada localidade / conjunto de caracteres:

  • sensível a maiúsculas e minúsculas
  • insensível a maiúsculas e minúsculas
  • insensível a maiúsculas e minúsculas, com preferência
  • insensível a maiúsculas e minúsculas

Você pode ver o relacionamento entre código de idioma, conjunto de caracteres e ordens de classificação disponíveis na página Seleção da ordem de classificação padrão . E você pode ver a lista completa de agrupamentos na página Nomes e IDs dos agrupamentos .

A convenção de nomenclatura de agrupamento é arbitrária, pois eles têm todos os caracteres de 4 a 8 e tentam capturar o nome da localidade ou a página de código e algum sentido da classificação. Por exemplo:

altnoacc== "CP 850 Alternativa - sem sotaque"
rusdict== "Pedido de dicionário em russo"
dynix== "Pedido fonético em chinês"

Há uma observação na página Selecionando a ordem de classificação padrão Unicode , informando:

Você pode adicionar ordens de classificação usando arquivos externos no $/collate/Unicodediretório Os nomes e os IDs de agrupamento são armazenados syscharsets. Os nomes das ordens de classificação Unicode externas não precisam estar dentro syscharsetspara que você possa definir a ordem de classificação Unicode padrão.
...
Ordens de classificação Unicode externas são fornecidas pela SAP. Não tente criar ordens de classificação Unicode externas.

Não está claro se a SAP forneceria ou não uma ordem de classificação externa para permitir diferenciação entre maiúsculas e minúsculas e sem sotaque. Talvez um dia eu os envie por e-mail e pergunte se um pode ser solicitado.

Para obter a combinação desejada de sensibilidades, você deve poder criar uma função escalar definida pelo usuário para remover acentos e outras marcas diacríticas.

Informix (comprado pela IBM)

O Informix parece apoiar principalmente o comportamento padrão de classificação e comparação de um agrupamento. Portanto, os agrupamentos são apenas o código de idioma e o conjunto de caracteres. A distinção entre maiúsculas e minúsculas é tratada no nível do banco de dados e, por padrão, diferenciam maiúsculas de minúsculas. Você pode definir um banco de dados (não uma tabela, uma coluna, uma consulta ou mesmo um predicado) para fazer distinção entre maiúsculas e minúsculas, especificando NLSCASE INSENSITIVE na CREATE DATABASEinstrução.

Embora o agrupamento do banco de dados - localidade e conjunto de caracteres - possa ser substituído por conexão do cliente, não parece haver uma maneira de substituir a configuração de distinção entre maiúsculas e minúsculas. E, a NLSCASEopção tem "NLS" no nome por um motivo: apenas afeta NCHARe NVARCHARdados; CHARe VARCHARsempre diferenciam maiúsculas de minúsculas.

A sensibilidade ao acento não é abordada, nem existe uma função interna para remover os acentos / marcas diacríticas.

A convenção de nomenclatura do Informix Collation é:

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

Onde:

  • <lang> = um código de idioma de duas ou três letras
  • <country> = um código de país ou região com duas letras
  • <code set> = a página de código especificada de uma das três maneiras equivalentes a seguir:
    • nome: 8859-1
    • valor decimal do número IBM CCSID: 819
    • valor hexadecimal do número IBM CCSID: 0333

Portanto, as três especificações de código de idioma a seguir se referem exatamente ao mesmo código de idioma:

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

Para mais informações, consulte:

Solomon Rutzky
fonte
11
@onedaywhen Desculpe pelo mal-entendido. O aspecto independente de fornecedor da pergunta não era totalmente claro, pois esse conceito realmente não existe, nem as Collations sempre usam essa convenção de nomenclatura. Reuni mais informações (por mais 3 RDBMSs) e estou atualizando minha resposta.
Solomon Rutzky
4
Desculpe pelo erro de digitação, mas eu quis dizer 'coloração', por exemplo, letras maiúsculas em azul e detalhes em vermelho ... só brincando! Esta é facilmente a melhor resposta que já recebi. Muito obrigado :) #
03716
@onedaywhen oooohhhh ... cor ... agora entendi ... felizmente essa é fácil: basta usar a --colorbandeira. No entanto, acho que isso só funciona se você enviar sua consulta usando JCL. ;-). Ou, se você quiser ver vermelho e azul, talvez a imagem usada nesta resposta seja suficiente? MAS, com uma observação séria: muito obrigado por esse maravilhoso elogio 😺. Além disso, adicionei informações para o SAP ASE e fiz algumas outras edições. Consulte o histórico de revisões para obter detalhes.
Solomon Rutzky
Atualização: O Postgres 10 ganha suporte para agrupamentos de UTI. Veja este post de Peter Eisentraut.
Basil Bourque
@BasilBourque Obrigado por mencionar isso sobre o PG10. No final, essa postagem do blog afirma que "a ICU oferece muitas funcionalidades nesta área que ainda não estamos expondo pelo PostgreSQL. Existem opções para classificação sem distinção entre maiúsculas e minúsculas, classificação sem distinção de sotaque e personalização total de um agrupamento. Veja para aqueles em versões futuras do PostgreSQL. " Portanto, em sua primeira / atual implementação, ela não altera nenhuma das informações na minha resposta. Se uma oferta futura permitir controle de sensibilidade de maiúsculas e minúsculas, atualizarei minha resposta com essas informações. Ótimo primeiro passo para o PG :-).
Solomon Rutzky
-3

Nome da opção Descrição NLS_LANG O conjunto de caracteres de idioma, território e banco de dados atual, que são determinados pelos parâmetros de globalização em toda a sessão. NLS_LANGUAGE O idioma atual da sessão. NLS_SORT A sequência de valores de caracteres usados ​​ao classificar ou comparar texto.

Para verificar as configurações atuais do NLS, digite:

selecione * de v $ NLS_PARAMETERS;

bax
fonte