O que 'COLLATE SQL_Latin1_General_CP1_CI_AS' faz?

134

Eu tenho uma consulta SQL para criar o banco de dados no SQLServer, conforme indicado abaixo:

create database yourdb
on
( name = 'yourdb_dat',
  filename = 'c:\program files\microsoft sql server\mssql.1\mssql\data\yourdbdat.mdf',
  size = 25mb,
  maxsize = 1500mb,
  filegrowth = 10mb )
log on
( name = 'yourdb_log',
  filename = 'c:\program files\microsoft sql server\mssql.1\mssql\data\yourdblog.ldf',
  size = 7mb,
  maxsize = 375mb,
  filegrowth = 10mb )
COLLATE SQL_Latin1_General_CP1_CI_AS;
go

Corre bem.

Enquanto o resto do SQL é claro, estou bastante confuso sobre a funcionalidade do COLLATE SQL_Latin1_General_CP1_CI_AS.

Alguém pode me explicar isso? Além disso, gostaria de saber se a criação do banco de dados dessa maneira é uma prática recomendada?

Trovão
fonte

Respostas:

246

Ele define como o servidor de banco de dados classifica (compara partes de texto). nesse caso:

SQL_Latin1_General_CP1_CI_AS

divide-se em partes interessantes:

  1. latin1 faz o servidor tratar strings usando charset latin 1, basicamente ascii
  2. CP1 significa Página de Código 1252
  3. CI comparações sem distinção entre maiúsculas e minúsculas, de modo que 'ABC' seria igual a 'abc'
  4. AS sotaque sensível, então 'ü' não é igual a 'u'

PS Para informações mais detalhadas, leia a resposta de @ solomon-rutzky .

Kris
fonte
11
Qual seria a diferença entre isso e SQL_Latin1_General_CI_AS. Especificamente, o CP1 me fez pensar.
Kad
7
@Kad: Não parece haver um SQL_Latin1_General_CI_AS. Pelo contrário, existe um Latin1_General_CI_AS. Veja SELECT * FROM fn_helpcollations() where name IN ('SQL_Latin1_General_CP1_CI_AS','Latin1_General_CI_AS','SQL_Latin1_General_CI_AS');. Existem diferenças sutis em relação à classificação e comparação entre os dois agrupamentos. Consulte olcot.co.uk/sql-blogs/… .
Riley Maior
4
@Kad: CP1 significa Página de Código 1252. Uma página de código é uma tabela de pesquisa para mapear o valor hexadecimal para um caractere específico em um conjunto de caracteres. CP1 é uma abreviação de CP1252 na subcultura da Microsoft. O Windows é a única plataforma que usa o CP1252 de forma independente, uma vez que é um atraso dos dias do DOS. Embora seja muito semelhante à ISO 8859-1, eles não são os mesmos. Existem diferenças nos caracteres mapeados como o euro e alguns outros que não estão na ISO 8859-1.
precisa saber é o seguinte
resposta perfeita @Kris!
gaurav
@Kris Existe alguma alternativa UTF-8 para SQL_Latin1_General_CP1_CI_AS no SQL2019?
Chanky 18/04
72

Esteja ciente de que a resposta aceita é um pouco incompleta. Sim, no nível mais básico, o agrupamento lida com a classificação. MAS, as regras de comparação definidas pelo agrupamento escolhido são usadas em muitos locais fora das consultas do usuário em relação aos dados do usuário.

Se "O que COLLATE SQL_Latin1_General_CP1_CI_ASfaz?" significa "O que faz a COLLATEcláusula de CREATE DATABASEfazer?", então:

A COLLATE {collation_name}cláusula da CREATE DATABASEinstrução especifica o agrupamento padrão do banco de dados , e não o servidor; Os agrupamentos padrão no nível do banco de dados e no servidor controlam coisas diferentes.

Controles de nível de servidor (ou seja, instância) :

  • Agrupamento de nível de banco de dados para bancos de dados do sistema: master, model, msdb, e tempdb.
  • Devido ao controle do agrupamento no nível do banco de dados tempdb, ele é o agrupamento padrão para colunas de sequência em tabelas temporárias (global e local), mas não variáveis ​​da tabela.
  • Devido ao controle do agrupamento no nível do banco de dados master, é o agrupamento usado para dados no nível do servidor , como nomes de banco de dados (por exemplo, namecoluna em sys.databases), nomes de logon etc.
  • Tratamento de nomes de parâmetros / variáveis
  • Manipulação de nomes de cursor
  • Manuseio de GOTOetiquetas
  • Agrupamento padrão usado para bancos de dados recém-criados quando a COLLATEcláusula está ausente

Controles no nível do banco de dados :

  • Padrão Agrupamento usado para colunas de cordas recém-criados ( CHAR, VARCHAR, NCHAR, NVARCHAR, TEXT, e NTEXT- mas não use TEXTou NTEXT) quando a COLLATEcláusula está faltando a definição da coluna. Isso vale para as instruções CREATE TABLEe ALTER TABLE ... ADD.
  • Agrupamento padrão usado para literais de sequência (ie 'some text') e variáveis ​​de sequência (ie @StringVariable). Esse agrupamento só é usado ao comparar cadeias e variáveis ​​com outras cadeias e variáveis. Ao comparar seqüências de caracteres / variáveis ​​com colunas, o agrupamento da coluna será usado.
  • O agrupamento usado para os metadados no nível do banco de dados, como nomes de objetos (ie sys.objects), nomes de colunas (ie sys.columns), nomes de índice (ie sys.indexes), etc.
  • O agrupamento usado para objetos no nível do banco de dados : tabelas, colunas, índices etc.

Além disso:

  • ASCII é uma codificação de 8 bits (para uso comum; tecnicamente "ASCII" é de 7 bits com valores de caracteres de 0 a 127 e "ASCII estendido" é de 8 bits com valores de caracteres de 0 a 255). Este grupo é o mesmo entre culturas.
  • A Página de código é a parte "estendida" do ASCII estendido e controla quais caracteres são usados ​​para os valores 128 - 255. Esse grupo varia entre cada cultura.
  • Latin1que não significa "ASCII" desde ASCII padrão cobre apenas os valores 0 - 127, e todas as páginas de código (que pode ser representado no SQL Server, e até mesmo NVARCHAR) mapear esses mesmos 128 valores para os mesmos personagens.

Se "O que COLLATE SQL_Latin1_General_CP1_CI_ASfaz?" significa "O que esse agrupamento específico faz?", então:

  • Como o nome começa SQL_, este é um agrupamento do SQL Server, não um agrupamento do Windows. Eles são definitivamente obsoletos, mesmo que não sejam oficialmente reprovados, e são principalmente para compatibilidade anterior ao SQL Server 2000. Embora, infelizmente, SQL_Latin1_General_CP1_CI_ASseja muito comum, por ser o padrão na instalação em um sistema operacional usando o inglês dos EUA como idioma. Esses agrupamentos devem ser evitados, se possível.

    Os agrupamentos do Windows (aqueles com nomes que não começam SQL_) são mais novos, mais funcionais, têm uma classificação consistente entre VARCHARe NVARCHARpara os mesmos valores e estão sendo atualizados com pesos de classificação adicionais / corrigidos e mapeamentos em maiúsculas / minúsculas. Esses agrupamentos também não apresentam o problema de desempenho potencial que os agrupamentos do SQL Server têm: Impacto nos índices ao misturar os tipos VARCHAR e NVARCHAR .

  • Latin1_General é a cultura / localidade.
    • Para NCHAR, NVARCHARe NTEXTdados determina as regras linguísticas usados para classificação e comparação.
    • Para CHAR, VARCHAR, e TEXTde dados (colunas, literais, e variáveis), o que determina a:
      • regras lingüísticas usadas para classificação e comparação.
      • página de código usada para codificar os caracteres. Por exemplo, Latin1_Generalagrupamentos usam a página de código 1252, Hebrewagrupamentos usam a página de código 1255 e assim por diante.
  • CP{code_page} ou {version}

    • Para agrupamentos do SQL Server :, CP{code_page}é a página de código de 8 bits que determina quais caracteres são mapeados para os valores de 128 a 255. Embora existam quatro páginas de código para DBCS (Conjuntos de Caracteres de Byte Duplo) que podem usar combinações de 2 bytes para criar mais de 256 caracteres, eles não estão disponíveis para os agrupamentos do SQL Server.
    • Para agrupamentos do Windows :, {version}embora não esteja presente em todos os nomes de agrupamentos, refere-se à versão do SQL Server na qual o agrupamento foi introduzido (na maior parte). Os agrupamentos do Windows sem número de versão no nome são version 80(significando SQL Server 2000 como versão 8.0). Nem todas as versões do SQL Server vêm com novos agrupamentos, portanto, existem lacunas nos números de versão. Existem alguns que são 90(para o SQL Server 2005, que é a versão 9.0), a maioria são 100(para o SQL Server 2008, versão 10.0) e um conjunto pequeno possui 140(para o SQL Server 2017, versão 14.0).

      Eu disse "na maioria das vezes" porque os agrupamentos terminados em _SCforam introduzidos no SQL Server 2012 (versão 11.0), mas os dados subjacentes não eram novos, eles apenas adicionaram suporte a caracteres suplementares para as funções internas. Portanto, essas terminações existem para versão 90e 100agrupamentos, mas apenas começando no SQL Server 2012.

  • Em seguida, você tem as sensibilidades, que podem estar em qualquer combinação do seguinte, mas sempre especificadas nesta ordem:
    • CS= diferencia maiúsculas de minúsculas ou CI= não diferencia maiúsculas de minúsculas
    • AS= sensível ao acento ou AI= insensível ao acento
    • KS = Kana sensível ao tipo ou ausente = Kana insensível ao tipo
    • WS = sensível à largura ou ausente = insensível à largura
    • VSS = sensível ao seletor de variação (disponível apenas nos agrupamentos da versão 140) ou ausente = insensível ao seletor de variação
  • Última peça opcional:

    • _SCno final significa "suporte a caracteres complementares". O "suporte" afeta apenas como as funções internas interpretam pares substitutos (que são como caracteres suplementares são codificados em UTF-16). Sem _SCno final (ou _140_no meio), as funções internas não veem um único caractere suplementar, mas sim dois pontos de código sem sentido que compõem o par substituto. Essa finalização pode ser adicionada a qualquer agrupamento não-binário, versão 90 ou 100.
    • _BINou _BIN2no final significa classificação e comparação "binárias". Os dados ainda são armazenados da mesma forma, mas não há regras lingüísticas. Esse final nunca é combinado com nenhuma das cinco sensibilidades ou _SC. _BINé o estilo mais antigo e _BIN2é o mais novo e mais preciso. Se estiver usando o SQL Server 2005 ou mais recente, use _BIN2. Para obter detalhes sobre as diferenças entre _BINe _BIN2, consulte: Diferenças entre as várias ordenações binárias (culturas, versões e BIN vs BIN2) .
    • _UTF8é uma nova opção a partir do SQL Server 2019. É uma codificação de 8 bits que permite que os dados Unicode sejam armazenados VARCHARe CHARtipos de dados (mas não o TEXTtipo de dados descontinuado ). Esta opção pode ser usada apenas em agrupamentos que suportam caracteres suplementares (por exemplo, agrupamentos da versão 90 ou 100 com _SCseus nomes e agrupamentos da versão 140). Há também um _UTF8agrupamento binário único ( _BIN2, não _BIN).

      OBSERVAÇÃO: O UTF-8 foi projetado / criado para compatibilidade com ambientes / códigos configurados para codificações de 8 bits, mas que desejam oferecer suporte ao Unicode. Embora existam alguns cenários em que o UTF-8 pode oferecer até 50% de economia de espaço em comparação NVARCHAR, isso é um efeito colateral e tem um custo de um pequeno impacto no desempenho em muitas / a maioria das operações. Se você precisar disso para compatibilidade, o custo é aceitável. Se você quer isso para economizar espaço, é melhor testar e testar novamente. Os testes incluem todas as funcionalidades e mais do que apenas algumas linhas de dados. Esteja avisado de que os agrupamentos UTF-8 funcionam melhor quando TODAS as colunas e o próprio banco de dados estão usando VARCHARdados (colunas, variáveis, literais de seqüência de caracteres) com um_UTF8agrupamento. Esse é o estado natural para quem usa isso para fins de compatibilidade, mas não para quem espera usá-lo para economizar espaço. Tenha cuidado ao misturar dados do VARCHAR usando um _UTF8agrupamento com VARCHARdados que não são _UTF8agrupamentos ou NVARCHARdados, pois você pode experimentar um comportamento estranho / perda de dados. Para obter mais detalhes sobre os novos agrupamentos UTF-8, consulte: Suporte nativo a UTF-8 no SQL Server 2019: Salvador ou Falso Profeta?

Solomon Rutzky
fonte
5
Enquanto eu votei isso por conter tanta informação e esforço, minha resposta definitivamente não está errada (os bancos de dados armazenam dados, os servidores de banco de dados atuam nesses dados, a classificação está agindo). Escolhi brevidade em vez de precisão matemática completa, porque o OP provavelmente estava procurando informações suficientes, nem todas as possíveis.
Kris
4
Olá @Kris. Obrigado. Para ser justo, eu não disse que sua resposta estava totalmente errada, apenas lamentavelmente incompleta. Eu atualizei para esclarecer isso. Entendi o que você está dizendo, mas o OP perguntou o que a COLLATEcláusula CREATE DATABASEfaz. Você disse uma das várias coisas que faz. Por que você supõe que o OP quer apenas 10% da resposta? Se todas as informações forem apresentadas, cada pessoa poderá decidir quanto será necessário. Mas se apenas algumas informações forem fornecidas, a escolha foi feita para elas. Eu escolho fornecer o máximo de informações possível, porque a maior parte não é bem conhecida. (continuação)
Solomon Rutzky 15/17
5
Acho que entendo o que você quer dizer, mas pretendo fornecer informações suficientes em vez de demais. muita informação rapidamente se torna muito complicada para muitas pessoas. e quando falhar em fornecer informações suficientes para qualquer circunstância, esperarei perguntas de acompanhamento. (Eu também não esperava bastante tanta atenção para o tema)
Kris
8
@Kris Eu tenho significado por um tempo para dizer "Obrigado!" por mostrar tal maturidade e profissionalismo. Estou um pouco acostumado a pessoas que se ofendem com alguém dizendo que estão erradas e depois se tornam "difíceis" (ou ainda mais difíceis) de interagir. Porém, sua resposta medida à minha "resposta aceita é ERRADA " me inspirou a diminuir minha introdução e deve servir de exemplo para outras pessoas aqui sobre como se comunicar de maneira adequada e produtiva 😺.
Solomon Rutzky
4
Você é bem-vindo e é bom ouvir que, de alguma forma, causei um impacto positivo, mas gosto de estar "errado", pois abre oportunidades para aprender coisas novas, o que é ótimo!
Kris
24

O CP1 significa 'Página de código 1' - tecnicamente, isso se traduz na página de código 1252

Chris Halcrow
fonte
16

A palavra-chave COLLATE especifica que tipo de conjunto de caracteres e regras (ordem, regras de confronto) você está usando para os valores da sequência.

Por exemplo, no seu caso, você está usando regras latinas com maiúsculas e minúsculas ( CI ) e acento sensível ( AS )

Você pode consultar esta documentação

il_guru
fonte
9

Isso especifica o agrupamento padrão para o banco de dados. Todo campo de texto que você criar nas tabelas do banco de dados usará esse agrupamento, a menos que você especifique outro.

Um banco de dados sempre tem um agrupamento padrão. Se você não especificar nenhum, o agrupamento padrão da instância do SQL Server será usado.

O nome do agrupamento que você usa mostra que ele usa a página de códigos Latin1 1, faz distinção entre maiúsculas e minúsculas (CI) e com acento sensível (AS). Esse agrupamento é usado nos EUA, portanto, conterá regras de classificação usadas nos EUA.

O agrupamento decide como os valores do texto são comparados em termos de igualdade e semelhança e como eles são comparados na classificação. A página de código é usada ao armazenar dados não unicode, por exemplo, campos varchar.

Guffa
fonte
errado (você não pode notespecificar um agrupamento, embora você pode aceitar o padrão) errada (ele é usado para dados unicode também)
RichardTheKiwi
@ Richard aka cyberkiwi: Verifique a documentação: msdn.microsoft.com/en-us/library/ms176061.aspx A especificação do agrupamento é opcional. A página de código não é usada para armazenar dados Unicode, pois eles são armazenados como pontos de código Unicode de 16 bits, e não como índices de página de código de 8 bits.
Guffa
Eu li sua resposta errada, mas ainda está errada. Um banco de dados sempre tem um agrupamento padrão = SERVIDOR , não especificamente Latin1_General_CI_AS. Agora eu li errado, porque eu meio que esperava que a declaração fosse sobre o agrupamento SERVER, o que requer aceitação do padrão na interface do usuário. Para o segundo ponto, você parece sugerir que o agrupamento não é usado para classificar dados unicode (mesmo que você alterne para sortingpara storingnas duas últimas frases). Os dados de texto Unicode também obedecem a agrupamentos.
RichardTheKiwi
@ Richard aka cyberkiwi: alterei o parágrafo sobre o agrupamento padrão para corresponder à documentação específica à qual vinculei. (Difere dependendo da versão do servidor.) Quanto ao segundo ponto, não consigo ver como poderia torná-lo mais claro. O texto diz que a página de código é usada ao armazenar dados não unicode. Uma página de código não é usada para determinar a classificação, nem para dados unicode nem para dados não unicode.
Guffa