Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Classement dans SQL Server

Présentation

Vous devez avoir déjà entendu le terme "Collation" dans SQL Server. Le classement est une configuration qui détermine la façon dont le tri des données de caractères est effectué. Il s'agit d'un paramètre important qui a un impact considérable sur le comportement du moteur de base de données SQL Server dans le traitement des données de caractères. Dans cet article, nous visons à discuter des classements en général et à montrer quelques exemples de gestion des classements.

Où puis-je trouver des classements ?

Vous pouvez trouver le classement SQL au niveau du serveur, de la base de données et de la colonne. Une autre chose importante à savoir est que le paramètre de classement n'a pas besoin d'être le même au niveau du serveur, de la base de données et de la colonne. Vous pouvez également mettre à jour vos requêtes pour utiliser des classements spécifiques. C'est à ce moment que vous vous rendrez compte de l'importance de configurer le bon classement dans votre environnement, car il existe un risque élevé de problèmes inattendus si le classement n'est pas cohérent.

Quels sont les différents types de classements disponibles ?

Vous pouvez obtenir la liste complète des classements disponibles en interrogeant la fonction système sys.fn_helpcollations()

select * from sys.fn_helpcollations()

Cela renverra la sortie suivante.

Si vous recherchez des classements spécifiques par langue, vous pouvez filtrer davantage le nom. Par exemple, si vous recherchez le classement pris en charge par la langue maorie, vous pouvez utiliser la requête suivante.

select * from sys.fn_helpcollations()
    where name like '%Maori%'

Cela renverra la sortie suivante.

De cette façon, vous pouvez vérifier les classements pris en charge pour le classement de votre choix. En interrogeant simplement la fonction système fn_helpcollations(), 5508 lignes au total ont été renvoyées, ce qui signifie qu'il y a autant de classements pris en charge. Notez que cela couvre la majorité des langues du monde.

Quelles sont les différentes options que vous voyez dans le nom du classement ?

Par exemple, dans ce classement :Maori_100_CS_AI_KS_WS_SC_UTF8, vous pouvez voir les différentes options dans le nom du classement.

CS – sensible à la casse
AI – insensible aux accents
KS – sensible au type kana
WS – sensible à la largeur
SC – caractères supplémentaires
UTF8 – Norme de codage
En fonction du type d'option de classement sélectionné, le moteur de base de données SQL Server fonctionnera différemment dans le traitement des données de caractères pour les opérations de tri et de recherche. Par exemple, si vous utilisez l'option sensible à la casse dans le classement SQL, le moteur de base de données se comportera différemment pour une opération de requête recherchant « Adam » ou « adam ». En supposant que vous ayez une table appelée "échantillon" et qu'il y ait une colonne de prénom avec un utilisateur "adam". La requête ci-dessous ne renverra aucun résultat s'il n'y a pas de ligne avec un prénom "Adam". Cela est dû à l'option "CS-Case sensitive" dans le classement.

select * from sample
    where firstname like '%Adam%'

Avec cet exemple simple, vous pouvez comprendre l'importance de choisir l'option de classement SQL correcte. Assurez-vous de bien comprendre les exigences de l'application avant de sélectionner le classement en premier lieu.

Rechercher le classement sur l'instance SQL Server

Vous pouvez obtenir le classement du serveur dans SQL Server Management Studio (SSMS) en cliquant avec le bouton droit sur l'instance SQL, puis en cliquant sur l'option "Propriétés" et en cochant l'onglet "Général". Ce classement est sélectionné par défaut lors de l'installation de SQL Server.

Vous pouvez également utiliser l'option serverproperty pour trouver la valeur de classement.

select SERVERPROPERTY('collation'),

Rechercher le classement d'une base de données SQL

Dans SSMS, cliquez avec le bouton droit sur la base de données SQL et accédez aux "Propriétés". Vous pouvez vérifier les détails de classement dans l'onglet "Général" comme indiqué ci-dessous.

Vous pouvez également utiliser la fonction databasepropertyex pour obtenir les détails d'un classement de base de données.

select DATABASEPROPERTYEX('Your DB Name','collation')

Rechercher le classement d'une colonne dans un tableau

Dans SSMS, accédez au tableau, puis aux colonnes, et enfin cliquez avec le bouton droit sur les colonnes individuelles pour afficher les "Propriétés". Si la colonne est d'un type de données caractère, vous verrez les détails du classement.

Cependant, en même temps, si vous vérifiez la valeur d'un type de données non alphanumérique, la valeur de classement sera nulle. Vous trouverez ci-dessous une capture d'écran d'une colonne dont le type de données est int.

Vous pouvez également utiliser un exemple de requête ci-dessous pour afficher les valeurs de classement des colonnes.

select sc.name, sc.collation_name from sys.columns sc
inner join sys.tables t on sc.object_id=t.object_id
where t.name='t1' – enter your table name

Vous trouverez ci-dessous le résultat de la requête.

Essayer différents classements dans les requêtes SQL

Dans cette section, nous verrons comment l'ordre de tri est impacté lorsque différents classements sont utilisés dans les requêtes. Un exemple de tableau est créé avec 2 colonnes comme indiqué ci-dessous.

La colonne fname a le classement par défaut de la base de données à laquelle elle appartient. Dans ce cas, la collation est SQL_Latin1_General_CP1_CI_AS.
Pour insérer quelques enregistrements dans la table, utilisez une requête ci-dessous. Attribuez vos propres valeurs aux paramètres.

insert into emp
  values (1,'mohammed')
  insert into emp 
  values (2,'moinudheen')
  insert into emp
  values (3,'Mohammed')
  insert into emp
  values (4,'Moinudheen')
  insert into emp
  values (5,'MOHAMMED')
  insert into emp
  values (6,'MOINUDHEEN')

Maintenant, interrogez la table emp et triez-la par la colonne fname en utilisant différents classements. Nous utiliserons le classement par défaut de la colonne pour le tri ainsi qu'un autre classement sensible à la casse - SQL_Latin1_General_CP1_CS_AS.

select * from emp order by fname collate SQL_Latin1_General_CP1_CS_AS 
select * from emp order by fname collate SQL_Latin1_General_CP1_CI_AS – this is default

Le résultat de ces requêtes est donné ci-dessous. Remarquez la différence dans le classement utilisé. Nous utilisons la casse au lieu de l'insensible à la casse.

Vous pouvez également vérifier les plans de requête pour ces deux requêtes pour repérer la différence. Sur le premier plan de requête où nous utilisons un classement différent de celui de la colonne, vous pouvez remarquer l'opérateur supplémentaire "Compute Scalar".

Lorsque vous passez la souris sur l'opérateur "Compute Scalar", vous verrez les détails supplémentaires comme indiqué ci-dessous. Cela est dû à la conversion implicite qui a lieu car nous utilisons un classement différent de celui par défaut utilisé dans la colonne.

Avec ce petit exemple, vous pouvez voir le type d'impact sur les performances des requêtes lorsque vous utilisez explicitement des classements dans les requêtes. Dans notre base de données de démonstration, nous avons utilisé une table simple, mais imaginons un scénario en temps réel où de petits changements dans les performances des requêtes peuvent entraîner des résultats inattendus.

Vérifier s'il est possible de modifier le classement au niveau de l'instance

Dans cette section, nous passerons en revue différents scénarios dans lesquels nous devrons peut-être modifier les classements par défaut. Vous pouvez rencontrer des situations où des serveurs ou des bases de données vous sont remis et ils peuvent ne pas respecter vos politiques standard, vous devrez donc peut-être modifier le classement. Le classement SQL Server par défaut est SQL_Latin1_General_CP1_CI_AS. Changer le classement au niveau de l'instance SQL n'est pas simple. Cela nécessite de scripter tous les objets dans les bases de données utilisateur, d'exporter les données, de supprimer les bases de données utilisateur, de reconstruire la base de données principale avec le nouveau classement, de créer les bases de données utilisateur, puis d'importer toutes les données. Donc, si vous installez de nouvelles instances SQL, assurez-vous simplement d'obtenir le bon classement la première fois, sinon vous devrez peut-être faire beaucoup de travail indésirable plus tard. Expliquer en détail les étapes de modification du classement au niveau de l'instance dépasse le cadre de cet article en raison des étapes détaillées requises pour chacune des étapes.

Modifier le classement au niveau de la base de données

Heureusement, la modification du classement au niveau de la base de données n'est pas aussi difficile que la modification du classement de l'instance. Nous pouvons mettre à jour le classement à l'aide de SSMS et de T-SQL. Dans SSMS, faites un clic droit sur la base de données, allez dans "Propriétés" et cliquez sur l'onglet "Options" sur le côté gauche. Là, vous pouvez voir l'option pour changer le classement dans le menu déroulant.

Cliquez sur "OK" une fois terminé. Je viens de changer le classement de la base de données en SQL_Latin1_General_CP1_CI_AS. Assurez-vous simplement que vous effectuez cette opération lorsque la base de données n'est pas utilisée, sinon l'opération échouera, comme indiqué ci-dessous.

Utilisez la requête précédente pour modifier le classement de la base de données à l'aide de T-SQL.

USE master;  
GO  
ALTER DATABASE mo  
COLLATE SQL_Latin1_General_CP1_CS_AS;  
GO

Vous remarquerez que la modification du classement au niveau de la base de données n'aura pas d'incidence sur le classement des colonnes existantes dans les tables. Vous pouvez utiliser les exemples précédents pour vérifier l'impact du classement sur l'ordre de tri pour les requêtes ci-dessous.

select * from emp order by fname collate SQL_Latin1_General_CP1_CS_AS 
select * from emp order by fname collate SQL_Latin1_General_CP1_CI_AS – - this is default

Le classement de la colonne fname restera celui d'origine et restera inchangé même après avoir modifié le classement au niveau de la base de données.

Cependant, le nouveau classement au niveau de la base de données sera appliqué pour toutes les nouvelles colonnes dans les nouvelles tables que vous allez créer. Par conséquent, testez toujours minutieusement la modification des classements de la base de données, car elle a un impact considérable sur la sortie ou le comportement des requêtes.

Modifier le classement au niveau de la colonne

Dans la section précédente, vous avez remarqué que même après avoir modifié le classement au niveau de la base de données, le classement des colonnes existantes dans les tables reste inchangé. Dans cette section, nous verrons comment modifier le classement des colonnes existantes dans les tables pour qu'il corresponde à celui du classement de la base de données. Dans la section précédente, vous avez changé le classement de la base de données en SQL_Latin1_General_CP1_CS_AS. Ensuite, vous souhaitez identifier toutes les colonnes des tables utilisateur qui ne correspondent pas à ce classement de base de données. Vous pouvez utiliser ce script pour identifier ces colonnes.

select so.name TableName,sc.name ColumnName, sc.collation_name CollationName from
sys.objects so inner join sys.columns sc on so.object_id=sc.object_id
where sc.collation_name!='SQL_Latin1_General_CP1_CS_AS' and so.[type] ='U'

L'exemple de sortie de ma base de données de démonstration est illustré ci-dessous.

Supposons que vous souhaitiez modifier le classement de la colonne fname existante en "SQL_Latin1_General_CP1_CS_AS", vous pouvez alors utiliser ce script alter ci-dessous.

use mo
go
ALTER TABLE dbo.emp ALTER COLUMN fname  
            nvarchar(20) COLLATE SQL_Latin1_General_CP1_CS_AS NULL;  
GO

Si vous utilisez les exemples précédents où vous avez vérifié les performances de la requête en utilisant différents classements, vous remarquerez que l'opérateur "compute scalar" n'est pas utilisé lorsque nous utilisons le même classement que celui de la base de données. Reportez-vous à la capture d'écran ci-dessous. Dans l'exemple précédent, vous avez peut-être remarqué que l'opérateur "Compute scalar" était utilisé dans le premier plan d'exécution. Comme nous avons modifié le classement des colonnes pour qu'il corresponde à celui du classement de la base de données, aucune conversion implicite n'est nécessaire. Vous verrez l'opérateur "Compute scalar" dans la deuxième requête car il utilise explicitement un classement différent.

select * from emp order by fname collate SQL_Latin1_General_CP1_CS_AS – - this is default
select * from emp order by fname collate SQL_Latin1_General_CP1_CI_AS

Pouvons-nous modifier le classement des bases de données système ?

La modification du classement des bases de données système n'est pas possible. Si vous essayez de modifier le classement des bases de données système - master, model, msdb ou tempdb, vous obtiendrez ce message d'erreur.

Vous devrez suivre les étapes décrites précédemment pour modifier le classement au niveau de l'instance SQL Server afin de modifier le classement des bases de données système. Il est important que les classements soient corrects la première fois que vous installez SQL Server pour éviter de tels problèmes.

Le problème connu du conflit de classement

Un autre problème courant que vous pouvez rencontrer est l'erreur liée au conflit de classement, en particulier lors de l'utilisation d'objets temporaires. Les objets temporaires sont stockés dans tempdb. Le tempdb étant une base de données système assumera le classement de l'instance SQL. Lorsque vous créez des bases de données utilisateur dont le classement est différent de celui de l'instance SQL, vous rencontrez des problèmes lors de l'utilisation d'objets temporaires. Vous pouvez également rencontrer des problèmes lors de la comparaison de colonnes dans des tables qui ont des classements différents. A présent, vous savez déjà qu'une table peut avoir des colonnes avec des classements différents car nous ne pouvons pas changer le classement au niveau de la table. Le message d'erreur courant que vous remarquerez est quelque chose comme "Impossible de résoudre le conflit de classement entre" Collation1 "et" Collation2 "dans l'opération égale à." Collation1 et Collation2 peuvent être n'importe quel classement utilisé dans une requête. À l'aide d'un exemple simple, nous pouvons produire une démonstration de ce conflit de classement. Si vous avez terminé les exemples précédents de cet article, vous aurez déjà une table nommée "emp". Créez simplement une table temporaire dans votre base de données de démonstration et insérez des enregistrements à l'aide de l'exemple de script fourni.

create table #emptemp
(id int,
 fname nvarchar(20))

insert into  #emptemp
select * from emp

Exécutez simplement une jointure en utilisant les deux tables et vous obtiendrez cette erreur de conflit de classement comme indiqué ci-dessous.

select e.id, et.fname 
from emp e inner join #emptemp et
on e.fname=et.fname

Vous remarquerez que le classement de la base de données utilisateur utilisé est "SQL_Latin1_General_CP1_CS_AS" et qu'il ne correspond pas à celui du classement du serveur. Afin de corriger ce type d'erreur, vous pouvez modifier les colonnes utilisées dans les objets temporaires pour utiliser le classement par défaut de la base de données utilisateur. Vous pouvez utiliser l'option "database_default" ou fournir explicitement le nom de classement de la base de données utilisateur. Dans cet exemple, nous utilisons le classement "SQL_Latin1_General_CP1_CS_AS". Essayez l'une de ces options
Option 1 : Utilisez l'option database_default

alter table #emptemp alter column
 fname nvarchar(20) collate database_default

Une fois cela fait, exécutez à nouveau l'instruction select et l'erreur sera corrigée.
Option 2 : Utiliser explicitement le classement de la base de données utilisateur

alter table #emptemp alter column
 fname nvarchar(20) collate SQL_Latin1_General_CP1_CS_AS

Une fois cela fait, exécutez à nouveau l'instruction select et l'erreur sera corrigée.

Conclusion

Dans cet article, vous avez découvert :
• le concept de classement
• les différentes options de classement disponibles
• la recherche de détails de classement pour n'importe quelle instance SQL, base de données et colonne
• Un EXEMPLE DE TRAVAIL sur l'essai des options de classement dans les requêtes SQL
• modification des classements au niveau de l'instance, de la base de données et des colonnes
• COMMENT modifier les classements des bases de données système
• un conflit de classement et comment pour le réparer

Vous connaissez maintenant l'importance du classement et l'importance de configurer le classement correct sur l'instance SQL et également sur les objets de la base de données. Testez toujours les différents scénarios sur votre environnement de test avant d'appliquer l'une des options ci-dessus sur vos systèmes de production.