O tipo de agrupamento padrão no SQL Server permite a indexação em relação a seqüências que não diferenciam maiúsculas de minúsculas, mas o caso dos dados é persistente. Como isso realmente funciona? Estou procurando as porcas e parafusos reais, bits e bytes, ou um bom recurso que explica isso em detalhes.
create table casetest (fruitnames nvarchar(50) not null);
create unique index IX_fruitnames on casetest(fruitnames);
insert into casetest values ('apples');
insert into casetest values ('Pears');
-- this insert fails
insert into casetest values ('pears');
-- this yields 'Pears' as a result
select * from casetest (forceseek) where fruitnames = 'PEARS'
update casetest set fruitnames = 'pears' where fruitnames = 'pEArs'
-- this yields 'pears' as a result
select * from casetest (forceseek) where fruitnames = 'PEARS'
Perguntas sobre agrupamentos do SQL Server que você era muito tímido para perguntar por Robert Sheldon aborda como usar o agrupamento. Não cobre como o agrupamento funciona. Estou interessado em saber como um índice pode ser criado / consultado com eficiência, sem se importar com o caso, enquanto simultaneamente armazena dados do caso.
sql-server
collation
cocogorilla
fonte
fonte
Respostas:
Na verdade, esse não é um comportamento específico do SQL Server, é apenas como essas coisas funcionam em geral.
Então, os dados são os dados. Se você estiver falando especificamente sobre um índice, os dados precisarão ser armazenados, pois, caso contrário, seria necessária uma consulta na tabela principal para obter o valor real e não haveria possibilidade de um índice de cobertura (em menos não para tipos de string).
Os dados, na tabela / índice agrupado ou não agrupado, não contêm nenhuma informação de agrupamento / classificação. São simplesmente dados. O agrupamento (regras de localização / cultura e sensibilidades) são apenas metadados anexados à coluna e usados quando uma operação de classificação é chamada (a menos que substituída por um
COLLATE
cláusula), que incluiria a criação / reconstrução de um índice. As regras definidas por um agrupamento não binário são usadas para gerar chaves de classificação, que são representações binárias da cadeia de caracteres (as chaves de classificação são desnecessárias em agrupamentos binários). Essas representações binárias incorporam todas as regras de localidade / cultura e sensibilidades selecionadas. As chaves de classificação são usadas para colocar os registros em sua ordem correta, mas não são elas próprias armazenadas no índice ou na tabela. Eles não são armazenados (pelo menos eu não vi esses valores no índice e foi informado que eles não são armazenados) porque:Existem dois tipos de agrupamentos: SQL Server e Windows.
servidor SQL
Os agrupamentos do SQL Server (aqueles com nomes começando com
SQL_
) são a maneira mais antiga de classificação / comparação anterior ao SQL Server 2000 (embora aindaSQL_Latin1_General_CP1_CI_AS
seja o padrão de instalação nos sistemas operacionais em inglês dos EUA, infelizmente). Nesse modelo mais antigo, simplista e não Unicode, cada combinação de código de idioma, página de códigos e várias sensibilidades recebe um mapeamento estático de cada um dos caracteres nessa página de códigos. Cada caractere recebe um valor (ou seja, peso da classificação) para indicar como ele se iguala aos outros. As comparações neste modelo parecem fazer uma operação de duas passagens:As únicas sensibilidades que podem ser ajustadas nessas intercalações são: "case" e "sotaque" ("width", "tipo de kana" e "seletor de variação" não estão disponíveis). Além disso, nenhum desses agrupamentos oferece suporte a caracteres suplementares (o que faz sentido, pois eles são específicos para Unicode e esses agrupamentos se aplicam apenas a dados não Unicode).
Essa abordagem se aplica apenas a
VARCHAR
dados não Unicode . Cada combinação exclusiva de localidade, página de código, distinção entre maiúsculas e minúsculas e distinção entre caracteres tem um "ID de classificação" específico, que você pode ver no exemplo a seguir:A única diferença entre os dois primeiros agrupamentos é a distinção entre maiúsculas e minúsculas. O terceiro agrupamento é um agrupamento do Windows e, portanto, não possui uma tabela de mapeamento estática.
Além disso, esses agrupamentos devem classificar e comparar mais rapidamente do que os agrupamentos do Windows devido à simples pesquisa de caracteres para classificar o peso. No entanto, esses agrupamentos também são muito menos funcionais e geralmente devem ser evitados, se possível.
janelas
Os agrupamentos do Windows (aqueles com nomes que não começam
SQL_
) são a maneira mais nova (começando no SQL Server 2000) de classificar / comparar. Nesse modelo Unicode mais novo e complexo, cada combinação de código do idioma, página de códigos e várias sensibilidades não recebe um mapeamento estático. Por um lado, não há páginas de código neste modelo. Esse modelo atribui um valor de classificação padrão a cada caractere e, em seguida, cada localidade / cultura pode atribuir novamente os valores de classificação a qualquer número de caracteres. Isso permite que várias culturas usem os mesmos caracteres de maneiras diferentes. Isso tem o efeito de permitir que vários idiomas sejam classificados naturalmente usando o mesmo agrupamento se eles não usarem os mesmos caracteres (e se um deles não precisar atribuir novamente nenhum valor e simplesmente usar os padrões).Os valores de classificação neste modelo não são valores únicos. Eles são uma matriz de valores que atribuem pesos relativos à letra base, quaisquer sinais diacríticos (por exemplo, acentos), letras maiúsculas e minúsculas etc. Se o agrupamento faz distinção entre maiúsculas e minúsculas, a parte "maiúscula" dessa matriz é usada, caso contrário, ela será ignorada ( portanto, insensível). Se o agrupamento for sensível ao acento, a parte "diacrítica" da matriz será usada, caso contrário, será ignorada (portanto, insensível).
As comparações neste modelo são uma operação de várias passagens:
Para obter mais detalhes sobre essa classificação, publicarei uma postagem que mostre os valores das chaves de classificação, como eles são calculados, as diferenças entre agrupamentos do SQL Server e do Windows, etc. Mas, por enquanto, consulte minha resposta para: Classificação sensível ao acento ( observe que a outra resposta a essa pergunta é uma boa explicação do algoritmo oficial Unicode, mas o SQL Server usa um algoritmo personalizado, embora semelhante, e até uma tabela de ponderação personalizada).
Todas as sensibilidades podem ser ajustadas nesses agrupamentos: "maiúsculas e minúsculas", "acento", "largura", "tipo de kana" e "seletor de variação" (a partir do SQL Server 2017 e apenas para os agrupamentos em japonês). Além disso, alguns desses agrupamentos (quando usados com dados Unicode) oferecem suporte a caracteres suplementares (a partir do SQL Server 2012). Essa abordagem se aplica aos dados
NVARCHAR
eVARCHAR
(mesmo que não sejam Unicode). Aplica-se aVARCHAR
dados não Unicode , primeiro convertendo o valor internamente em Unicode e aplicando as regras de classificação / comparação.Observe:
SQL_Latin1_General_CP1_CI_AS
para sistemas em inglês dos EUA, então vote nesta sugestão ). Isso pode ser alterado durante a instalação. Esse agrupamento no nível da instância define o agrupamento para o[model]
banco de dados, que é o modelo usado ao criar novos bancos de dados, mas o agrupamento pode ser alterado durante a execuçãoCREATE DATABASE
, especificando aCOLLATE
cláusula. Esse agrupamento no nível do banco de dados é usado para literais de variáveis e seqüências de caracteres, bem como o padrão para novas colunas (e alteradas!) Quando aCOLLATE
cláusula não é especificada (que é o caso do código de exemplo na pergunta).fonte
Normalmente, isso é implementado usando tabelas de agrupamento que atribuem uma certa pontuação a cada personagem. A rotina de classificação possui um comparador que usa uma tabela apropriada, padrão ou especificada explicitamente, para comparar cadeias, caractere por caractere, usando suas pontuações de ordenação. Se, por exemplo, uma tabela de intercalação específica atribuir uma pontuação de 1 a "a" e 201 a "A", e uma pontuação mais baixa nessa implementação específica significar maior precedência, então "a" será classificado antes de "A". Outra tabela pode atribuir pontuações reversas: 201 a "a" e 1 a "A", e a ordem de classificação será subsequentemente inversa. Ainda outra tabela pode atribuir pontuações iguais a "a", "A", "Á" e "Å", o que levaria a uma comparação e classificação sem distinção entre maiúsculas e minúsculas.
Da mesma forma, um comparador baseado em tabela de intercalação usado ao comparar uma chave de índice com o valor fornecido no predicado.
fonte
SQL_
) quando usados nosVARCHAR
dados. Isso não é exatamente verdadeiro paraNVARCHAR
dados ouVARCHAR
dados ao usar um agrupamento do Windows (nomes que não começam comSQL_
).