Que fait 'COLLATE SQL_Latin1_General_CP1_CI_AS'?

134

J'ai une requête SQL pour créer la base de données dans SQLServer comme indiqué ci-dessous:

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

Cela fonctionne bien.

Bien que le reste du SQL soit clair, je suis assez confus quant à la fonctionnalité de COLLATE SQL_Latin1_General_CP1_CI_AS.

Quelqu'un peut-il m'expliquer cela? Aussi, je voudrais savoir si créer la base de données de cette manière est une bonne pratique?

Tonnerre
la source

Réponses:

246

Il définit la manière dont le serveur de base de données trie (compare des morceaux de texte). dans ce cas:

SQL_Latin1_General_CP1_CI_AS

se décompose en parties intéressantes:

  1. latin1 fait que le serveur traite les chaînes en utilisant charset latin 1, essentiellement ascii
  2. CP1 signifie Page de code 1252
  3. CI comparaisons insensibles à la casse, donc «ABC» serait égal à «abc»
  4. AS sensible à l'accent, donc «ü» n'est pas égal à «u»

PS Pour plus d'informations, assurez-vous de lire la réponse de @ solomon-rutzky .

Kris
la source
11
Quelle serait la différence entre ceci et SQL_Latin1_General_CI_AS. Plus précisément, CP1 m'a fait me demander.
Kad
7
@Kad: Il ne semble pas y avoir de fichier SQL_Latin1_General_CI_AS. Au contraire, il y a un Latin1_General_CI_AS. Voir SELECT * FROM fn_helpcollations() where name IN ('SQL_Latin1_General_CP1_CI_AS','Latin1_General_CI_AS','SQL_Latin1_General_CI_AS');. Il existe des différences subtiles concernant le tri et la comparaison entre les deux classements. Voir olcot.co.uk/sql-blogs/… .
Riley Major
4
@Kad: CP1 signifie Page de code 1252. Une page de codes est une table de recherche pour mapper la valeur hexadécimale à un caractère spécifique dans un jeu de caractères. CP1 est un raccourci pour CP1252 dans la sous-culture Microsoft. Windows est la seule plate-forme qui utilise le CP1252 localement, car il s'agit d'un résidu des jours DOS. Bien qu'elle soit très similaire à ISO 8859-1, elles ne sont pas les mêmes. Il existe des différences dans les caractères mappés comme l'euro et quelques autres qui ne sont pas dans l'ISO 8859-1.
slartibartfast
réponse impeccable @Kris!
gaurav
@Kris Existe-t-il une alternative UTF-8 pour SQL_Latin1_General_CP1_CI_AS dans SQL2019?
Chanky
72

Veuillez noter que la réponse acceptée est un peu incomplète. Oui, au niveau le plus élémentaire, le classement gère le tri. MAIS, les règles de comparaison définies par le classement choisi sont utilisées dans de nombreux endroits en dehors des requêtes utilisateur sur les données utilisateur.

Si "Que fait COLLATE SQL_Latin1_General_CP1_CI_AS-on?" signifie "Que fait la COLLATEclause de CREATE DATABASE?", puis:

La COLLATE {collation_name}clause de l' CREATE DATABASEinstruction spécifie le classement par défaut de la base de données et non du serveur; Les classements par défaut au niveau de la base de données et au niveau du serveur contrôlent des choses différentes.

Contrôles au niveau du serveur (c'est-à-dire Instance) :

  • Base de données de niveau Collation pour système de bases de données: master, model, msdbet tempdb.
  • En raison du contrôle du classement au niveau de la base de données de tempdb, il s'agit alors du classement par défaut pour les colonnes de chaîne dans les tables temporaires (globales et locales), mais pas pour les variables de table.
  • En raison du contrôle du classement au niveau de la base de données de master, il s'agit alors du classement utilisé pour les données au niveau du serveur , telles que les noms de base de données (c'est-à-dire la namecolonne dans sys.databases), les noms de connexion, etc.
  • Gestion des noms de paramètres / variables
  • Gestion des noms de curseur
  • Manipulation des GOTOétiquettes
  • Classement par défaut utilisé pour les bases de données nouvellement créées lorsque la COLLATEclause est manquante

Contrôles au niveau de la base de données :

  • Par défaut Collation utilisé pour les colonnes de chaîne nouvellement créées ( CHAR, VARCHAR, NCHAR, NVARCHAR, TEXTet NTEXT- mais ne pas utiliser TEXTou NTEXT) lorsque la COLLATEclause est absente de la définition de la colonne. Cela vaut pour les déclarations CREATE TABLEet ALTER TABLE ... ADD.
  • Classement par défaut utilisé pour les chaînes littérales (ie 'some text') et les variables de chaîne (ie @StringVariable). Ce classement n'est utilisé que lors de la comparaison de chaînes et de variables avec d'autres chaînes et variables. Lors de la comparaison de chaînes / variables avec des colonnes, le classement de la colonne sera utilisé.
  • Le classement utilisé pour les métadonnées au niveau de la base de données, telles que les noms d'objet (ie sys.objects), les noms de colonne (ie sys.columns), les noms d'index (ie sys.indexes), etc.
  • Le classement utilisé pour les objets de niveau base de données : tables, colonnes, index, etc.

Aussi:

  • ASCII est un codage de 8 bits (pour un usage courant; techniquement, "ASCII" est de 7 bits avec des valeurs de caractères de 0 à 127 et "ASCII Extended" est de 8 bits avec des valeurs de caractères de 0 à 255). Ce groupe est le même dans toutes les cultures.
  • La page de codes est la partie «étendue» de l'ASCII étendu et contrôle les caractères utilisés pour les valeurs 128 à 255. Ce groupe varie d'une culture à l'autre.
  • Latin1ne signifie pas «ASCII» car l'ASCII standard ne couvre que les valeurs 0 à 127 et toutes les pages de codes (qui peuvent être représentées dans SQL Server et même NVARCHAR) mappent ces 128 mêmes valeurs aux mêmes caractères.

Si "Que fait COLLATE SQL_Latin1_General_CP1_CI_AS-on?" signifie "Que fait ce classement particulier?", puis:

  • Étant donné que le nom commence par SQL_, il s'agit d'un classement SQL Server, pas d'un classement Windows. Ceux-ci sont définitivement obsolètes, même s'ils ne sont pas officiellement obsolètes, et sont principalement destinés à la compatibilité pré-SQL Server 2000. Bien que, malheureusement, il SQL_Latin1_General_CP1_CI_ASsoit très courant car il s'agit de la valeur par défaut lors de l'installation sur un système d'exploitation utilisant l'anglais américain comme langue. Ces classements doivent être évités dans la mesure du possible.

    Les classements Windows (ceux dont les noms ne commencent pas par SQL_) sont plus récents, plus fonctionnels, ont un tri cohérent entre VARCHARet NVARCHARpour les mêmes valeurs, et sont mis à jour avec des poids de tri supplémentaires / corrigés et des mappages majuscules / minuscules. Ces classements n'ont pas non plus le problème de performances potentiel que présentent les classements SQL Server: Impact sur les index lors du mélange des types VARCHAR et NVARCHAR .

  • Latin1_General est la culture / locale.
    • Pour NCHAR, NVARCHARet les NTEXTdonnées ce qui détermine les règles linguistiques utilisées pour le tri et la comparaison.
    • Pour CHAR, VARCHARet TEXTdonnées (colonnes, littéraux et variables) ce qui détermine le:
      • règles linguistiques utilisées pour le tri et la comparaison.
      • page de code utilisée pour encoder les caractères. Par exemple, les Latin1_Generalclassements utilisent la page de codes 1252, les Hebrewclassements utilisent la page de codes 1255, etc.
  • CP{code_page} ou {version}

    • Pour les classements SQL Server :, CP{code_page}est la page de codes 8 bits qui détermine les caractères mappés aux valeurs 128 à 255. Bien qu'il existe quatre pages de codes pour les jeux de caractères à deux octets (DBCS) qui peuvent utiliser des combinaisons de 2 octets pour créer plus de 256 caractères, ils ne sont pas disponibles pour les classements SQL Server.
    • Pour les classements Windows :, bien {version}qu'il ne soit pas présent dans tous les noms de classement, fait référence à la version de SQL Server dans laquelle le classement a été introduit (pour la plupart). Les classements Windows sans numéro de version dans le nom sont version 80(ce qui signifie SQL Server 2000 car il s'agit de la version 8.0). Toutes les versions de SQL Server ne sont pas livrées avec de nouveaux classements, il y a donc des lacunes dans les numéros de version. Il y en a qui le sont 90(pour SQL Server 2005, qui est la version 9.0), la plupart le sont 100(pour SQL Server 2008, version 10.0) et un petit ensemble a 140(pour SQL Server 2017, version 14.0).

      J'ai dit «pour la plupart» parce que les classements se terminant par _SCont été introduits dans SQL Server 2012 (version 11.0), mais les données sous-jacentes n'étaient pas nouvelles, elles ont simplement ajouté la prise en charge de caractères supplémentaires pour les fonctions intégrées. Ainsi, ces fins existent pour la version 90et les 100classements, mais uniquement à partir de SQL Server 2012.

  • Ensuite, vous avez les sensibilités, qui peuvent être dans n'importe quelle combinaison des éléments suivants, mais toujours spécifiées dans cet ordre:
    • CS= sensible à la casse ou CI= insensible à la casse
    • AS= sensible à l' AIaccent ou = insensible à l'accent
    • KS = Kana sensible au type ou manquant = Kana insensible au type
    • WS = sensible à la largeur ou manquant = insensible à la largeur
    • VSS = sélecteur de variation sensible (uniquement disponible dans les classements version 140) ou manquant = sélecteur de variation insensible
  • Dernière pièce optionnelle:

    • _SCà la fin signifie "Prise en charge des caractères supplémentaires". Le "support" affecte uniquement la façon dont les fonctions intégrées interprètent les paires de substitution (qui sont la façon dont les caractères supplémentaires sont codés en UTF-16). Sans _SCà la fin (ou _140_au milieu), les fonctions intégrées ne voient pas un seul caractère supplémentaire, mais voient à la place deux points de code dénués de sens qui composent la paire de substitution. Cette fin peut être ajoutée à n'importe quel classement non binaire, version 90 ou 100.
    • _BINou _BIN2à la fin signifie le tri et la comparaison «binaires». Les données sont toujours stockées de la même manière, mais il n'y a pas de règles linguistiques. Cette fin n'est jamais combinée avec aucune des 5 sensibilités ou _SC. _BINest le style le plus ancien et le style _BIN2le plus récent et le plus précis. Si vous utilisez SQL Server 2005 ou plus récent, utilisez _BIN2. Pour plus de détails sur les différences entre _BINet _BIN2, veuillez consulter: Différences entre les divers classements binaires (cultures, versions et BIN vs BIN2) .
    • _UTF8est une nouvelle option à partir de SQL Server 2019. Il s'agit d'un codage 8 bits qui permet de stocker les données Unicode dans VARCHARet les CHARtypes de données (mais pas le TEXTtype de données obsolète ). Cette option ne peut être utilisée que sur les classements qui prennent en charge les caractères supplémentaires (c'est-à-dire les classements de la version 90 ou 100 avec _SCdans leur nom et les classements de la version 140). Il existe également un seul _UTF8classement binaire ( _BIN2, non _BIN).

      VEUILLEZ NOTER: UTF-8 a été conçu / créé pour être compatible avec les environnements / codes configurés pour les encodages 8 bits tout en souhaitant prendre en charge Unicode. Même s'il existe quelques scénarios dans lesquels UTF-8 peut fournir jusqu'à 50% d'économie d'espace par rapport à NVARCHAR, c'est un effet secondaire et cela a un coût d'un léger impact sur les performances dans de nombreuses / la plupart des opérations. Si vous en avez besoin pour la compatibilité, le coût est acceptable. Si vous voulez cela pour gagner de la place, vous feriez mieux de tester et de tester à nouveau. Les tests incluent toutes les fonctionnalités et bien plus que quelques lignes de données. Soyez averti que les classements UTF-8 fonctionnent mieux lorsque TOUTES les colonnes, et la base de données elle-même, utilisent des VARCHARdonnées (colonnes, variables, littéraux de chaîne) avec un_UTF8collation. C'est l'état naturel pour quiconque l'utilise pour la compatibilité, mais pas pour ceux qui espèrent l'utiliser pour économiser de l'espace. Soyez prudent lorsque vous mélangez des données VARCHAR à l'aide d'un _UTF8classement avec des VARCHARdonnées utilisant des non- _UTF8collations ou des NVARCHARdonnées, car vous pourriez rencontrer un comportement étrange / une perte de données. Pour plus de détails sur les nouveaux classements UTF-8, veuillez consulter: Prise en charge native d'UTF-8 dans SQL Server 2019: Savior ou False Prophet?

Solomon Rutzky
la source
5
Bien que j'aie voté pour cela pour contenir tant d'informations et d'efforts, ma réponse n'est certainement pas fausse (les bases de données stockent des données, les serveurs de bases de données agissent sur ces données, le tri agit). J'ai choisi la brièveté plutôt que la précision mathématique complète parce que l'OP recherchait probablement suffisamment d'informations, pas toutes les informations possibles.
Kris le
4
Salut @Kris. Merci. Pour être honnête, je n'ai pas dit que votre réponse était totalement erronée, mais malheureusement incomplète. J'ai mis à jour pour clarifier cela, espérons-le. Je comprends ce que vous dites, mais le PO a demandé ce que COLLATEfaisait l' article de CREATE DATABASE. Vous avez dit l'une des nombreuses choses qu'il fait. Pourquoi pensez-vous que le PO ne veut connaître que 10% de la réponse? Si toutes les informations sont présentées, chaque personne peut décider de la quantité à prendre. Mais si seulement quelques informations sont données, le choix a été fait pour eux. Je choisis de fournir autant d'informations que possible car la plupart d'entre elles ne sont pas bien connues. (suite)
Solomon Rutzky
5
Je pense que je vois ce que vous voulez dire, mais je vise à donner suffisamment d'informations plutôt que trop. trop d'informations devient rapidement trop compliquée pour beaucoup de gens. et quand je ne donne pas suffisamment d'informations pour quelque circonstance que ce soit, je m'attends à des questions de suivi. (Je ne m'attendais pas non plus à autant d'attention sur le sujet)
Kris
8
@Kris Cela fait un moment que je veux dire "Merci!" pour avoir fait preuve d’une telle maturité et d’un tel professionnalisme. Je suis un peu habitué à ce que les gens s'offusquent personnellement à quelqu'un en disant qu'ils ont tort, et deviennent alors «difficiles» (voire plus difficiles) avec lesquels interagir. Mais, votre réponse mesurée à mon, "la réponse acceptée est FAUX " m'a inspiré pour atténuer mon intro, et devrait servir d'exemple aux autres ici sur la façon de communiquer correctement et de manière productive 😺.
Solomon Rutzky
4
Vous êtes le bienvenu et agréable d'entendre que j'ai en quelque sorte eu un impact positif, mais j'aime me tromper, cela ouvre des opportunités d'apprendre de nouvelles choses, ce qui est génial!
Kris
24

Le CP1 signifie 'Code Page 1' - techniquement cela se traduit par la page de code 1252

Chris Halcrow
la source
16

Le mot clé COLLATE spécifie le type de jeu de caractères et de règles (ordre, règles de confrontation) que vous utilisez pour les valeurs de chaîne.

Par exemple, dans votre cas, vous utilisez des règles latines avec insensible à la casse ( CI ) et sensible à l'accent ( AS )

Vous pouvez vous référer à cette documentation

il_guru
la source
9

Cela spécifie le classement par défaut de la base de données. Chaque champ de texte que vous créez dans les tables de la base de données utilisera ce classement, sauf si vous en spécifiez un différent.

Une base de données a toujours un classement par défaut. Si vous n'en spécifiez aucun, le classement par défaut de l'instance SQL Server est utilisé.

Le nom du classement que vous utilisez indique qu'il utilise la page de codes Latin1 1, qu'il est insensible à la casse (CI) et aux accents (AS). Ce classement est utilisé aux États-Unis, il contiendra donc les règles de tri utilisées aux États-Unis.

Le classement décide comment les valeurs de texte sont comparées pour l'égalité et la ressemblance, et comment elles sont comparées lors du tri. La page de codes est utilisée lors du stockage de données non-Unicode, par exemple des champs varchar.

Guffa
la source
faux (vous ne pouvez pas notspécifier de classement, bien que vous puissiez accepter la valeur par défaut) faux (il est également utilisé pour les données Unicode)
RichardTheKiwi
@Richard aka cyberkiwi: Consultez la documentation: msdn.microsoft.com/en-us/library/ms176061.aspx La spécification du classement est facultative. La page de codes n'est pas utilisée pour stocker les données Unicode, car elles sont stockées en tant que points de code Unicode 16 bits, et non en tant qu'index de page de codes 8 bits.
Guffa
J'ai mal lu votre réponse, mais c'est toujours faux. Une base de données a toujours un classement par défaut = classement SERVER , pas spécifiquement Latin1_General_CI_AS. Maintenant, je l'ai mal lu car je m'attendais à moitié à ce que la déclaration concerne le classement SERVER, ce qui nécessite l'acceptation de la valeur par défaut dans l'interface utilisateur. Pour le 2ème point, vous semblez impliquer que le classement n'est pas utilisé pour trier les données Unicode (même si vous passez de sortingà storingdans les 2 dernières phrases). Les données texte Unicode obéissent également aux classements.
RichardTheKiwi
@Richard aka cyberkiwi: J'ai changé le paragraphe sur le classement par défaut pour qu'il corresponde à la documentation spécifique à laquelle j'ai lié. (Cela diffère selon la version du serveur.) Concernant le deuxième point, je ne vois pas comment je pourrais le rendre plus clair. Le texte indique que la page de codes est utilisée lors du stockage de données non-Unicode. Une page de codes n'est pas utilisée pour déterminer le tri, ni pour les données Unicode, ni pour les données non Unicode.
Guffa