Le type de classement par défaut dans SQL Server permet l'indexation par rapport aux chaînes insensibles à la casse, mais la casse des données est persistante. Comment cela fonctionne-t-il réellement? Je cherche les vrais écrous et boulons, bits et octets, ou une bonne ressource qui l'explique en détail.
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'
Questions sur les classements SQL Server que vous étiez trop timides à poser par Robert Sheldon couvre comment utiliser le classement. Il ne couvre pas le fonctionnement du classement. Je suis intéressé par la façon dont un index peut être efficacement créé / interrogé sans se soucier du cas, tout en stockant simultanément les données du cas.
sql-server
collation
cocogorilla
la source
la source
Réponses:
Ce n'est en fait pas un comportement spécifique à SQL Server, c'est juste comment ces choses fonctionnent en général.
Ainsi, les données sont les données. Si vous parlez spécifiquement d'un index, les données doivent être stockées car sinon, cela nécessiterait une recherche dans la table principale à chaque fois pour obtenir la valeur réelle, et il n'y aurait aucune possibilité d'index de couverture (à pas pour les types de chaînes).
Les données, que ce soit dans l'index de table / cluster ou index non ordonnés en clusters, ne pas contenir aucune collation / informations de tri. Ce sont simplement des données. Le classement (règles locales / culturelles et sensibilités) n'est que des métadonnées attachées à la colonne et utilisées lorsqu'une opération de tri est appelée (sauf si elle est remplacée par un
COLLATE
), qui comprendrait la création / reconstruction d'un index. Les règles définies par un classement non binaire sont utilisées pour générer des clés de tri, qui sont des représentations binaires de la chaîne (les clés de tri ne sont pas nécessaires dans les classements binaires). Ces représentations binaires incorporent toutes les règles locales / culturelles et les sensibilités sélectionnées. Les clés de tri sont utilisées pour placer les enregistrements dans leur ordre correct, mais elles ne sont pas elles-mêmes stockées dans l'index ou la table. Ils ne sont pas stockés (au moins je n'ai pas vu ces valeurs dans l'index et on m'a dit qu'ils ne sont pas stockés) parce que:Il existe deux types de classements: SQL Server et Windows.
serveur SQL
Les classements SQL Server (ceux dont le nom commence par
SQL_
) sont la méthode de tri / comparaison antérieure à SQL Server 2000 (même si , malheureusement,SQL_Latin1_General_CP1_CI_AS
c'est toujours l'installation par défaut sur les systèmes d'exploitation en anglais américain). Dans ce modèle ancien, simpliste et non Unicode, chaque combinaison de paramètres régionaux, de page de codes et des différentes sensibilités reçoit un mappage statique de chacun des caractères de cette page de codes. Chaque caractère se voit attribuer une valeur (c.-à-d. Un poids de tri) pour indiquer comment il correspond aux autres. Les comparaisons dans ce modèle semblent faire une opération en deux passes:Les seules sensibilités pouvant être ajustées dans ces classements sont: "case" et "accent" ("width", "kana type" et "variation selector" ne sont pas disponibles). En outre, aucun de ces classements ne prend en charge les caractères supplémentaires (ce qui est logique car ceux-ci sont spécifiques à Unicode et ces classements ne s'appliquent qu'aux données non Unicode).
Cette approche s'applique uniquement aux
VARCHAR
données non Unicode . Chaque combinaison unique de paramètres régionaux, de page de codes, de respect de la casse et de sensibilité aux accents possède un "ID de tri" spécifique, que vous pouvez voir dans l'exemple suivant:La seule différence entre les deux premiers classements est la sensibilité à la casse. Le troisième classement est un classement Windows et n'a donc pas de table de mappage statique.
En outre, ces classements doivent être triés et comparés plus rapidement que les classements Windows en raison de la simple recherche de caractères pour trier le poids. Cependant, ces classements sont également beaucoup moins fonctionnels et devraient généralement être évités si possible.
les fenêtres
Les classements Windows (ceux dont le nom ne commence pas par
SQL_
) sont la méthode de tri / comparaison la plus récente (à partir de SQL Server 2000). Dans ce modèle Unicode plus récent et complexe, chaque combinaison de paramètres régionaux, de page de codes et des différentes sensibilités ne reçoit pas de mappage statique. D'une part, il n'y a pas de pages de codes dans ce modèle. Ce modèle attribue une valeur de tri par défaut à chaque caractère, puis chaque environnement local / culture peut réaffecter des valeurs de tri à n'importe quel nombre de caractères. Cela permet à plusieurs cultures d'utiliser les mêmes personnages de différentes manières. Cela a pour effet de permettre le tri naturel de plusieurs langues en utilisant le même classement si elles n'utilisent pas les mêmes caractères (et si l'une d'entre elles n'a pas besoin de réaffecter de valeurs et peut simplement utiliser les valeurs par défaut).Les valeurs de tri dans ce modèle ne sont pas des valeurs uniques. Il s'agit d'un tableau de valeurs qui attribuent des poids relatifs à la lettre de base, à tous les signes diacritiques (c'est-à-dire les accents), à la casse, etc. Si le classement est sensible à la casse, alors la partie "casse" de ce tableau est utilisée, sinon il est ignoré ( donc insensible). Si le classement est sensible à l'accent, la partie "diacritique" du tableau est utilisée, sinon elle est ignorée (donc insensible).
Les comparaisons dans ce modèle sont une opération à plusieurs passes:
Pour plus de détails sur ce tri, je vais finir par publier un billet qui montre les valeurs, la façon dont elles sont calculées, les différences entre SQL Server et les classements Windows, etc. Mais pour l' instant, s'il vous plaît voir ma clé de tri réponse à: Accent Trier sensible ( veuillez noter que l'autre réponse à cette question est une bonne explication de l'algorithme Unicode officiel, mais SQL Server utilise à la place un algorithme personnalisé, bien que similaire, et même une table de pondération personnalisée).
Toutes les sensibilités peuvent être ajustées dans ces classements: "case", "accent", "width", "kana type" et "variation selector" (à partir de SQL Server 2017, et uniquement pour les classements japonais). En outre, certains de ces classements (lorsqu'ils sont utilisés avec des données Unicode) prennent en charge les caractères supplémentaires (à partir de SQL Server 2012). Cette approche applique à la fois
NVARCHAR
etVARCHAR
les données (même de données non-Unicode). Il s'applique auxVARCHAR
données non Unicode en convertissant d'abord la valeur en Unicode en interne, puis en appliquant les règles de tri / comparaison.Notez s'il vous plaît:
SQL_Latin1_General_CP1_CI_AS
pour les systèmes en anglais américain, alors veuillez voter pour cette suggestion ). Cela peut être modifié pendant l'installation. Ce classement au niveau de l'instance définit ensuite le classement pour la base de[model]
données qui est le modèle utilisé lors de la création de nouvelles bases de données, mais le classement peut être modifié lors de l'exécutionCREATE DATABASE
en spécifiant laCOLLATE
clause. Ce classement au niveau de la base de données est utilisé pour les littéraux de variable et de chaîne, ainsi que par défaut pour les nouvelles colonnes (et modifiées!) Lorsque laCOLLATE
clause n'est pas spécifiée (ce qui est le cas pour l'exemple de code dans la question).la source
En règle générale, cela est mis en œuvre à l'aide de tables de classement qui attribuent un certain score à chaque personnage. La routine de tri a un comparateur qui utilise une table appropriée, par défaut ou spécifiée explicitement, pour comparer les chaînes, caractère par caractère, en utilisant leurs scores de classement. Si, par exemple, une table de classement particulière attribue un score de 1 à "a" et de 201 à "A", et un score inférieur dans cette implémentation particulière signifie une priorité plus élevée, alors "a" sera trieur avant "A". Un autre tableau peut attribuer des scores inversés: 201 à "a" et 1 à "A", et l'ordre de tri sera ensuite inversé. Encore un autre tableau pourrait attribuer des scores égaux à "a", "A", "Á" et "Å", ce qui conduirait à une comparaison et un tri insensibles à la casse et à l'accent.
De même, un tel comparateur basé sur une table de classement est utilisé lors de la comparaison d'une clé d'index avec la valeur fournie dans le prédicat.
la source
SQL_
) lorsqu'ils sont utilisés sur desVARCHAR
données. Ce n'est pas exactement vrai pour lesNVARCHAR
données ou lesVARCHAR
données lors de l'utilisation d'un classement Windows (noms ne commençant pas parSQL_
).