web-dev-qa-db-fra.com

Quand devons-nous utiliser NVARCHAR/NCHAR au lieu de VARCHAR/CHAR dans SQL Server?

Existe-t-il une règle lorsque nous devons utiliser les types Unicode? 

J'ai vu que la plupart des langues européennes (allemand, italien, anglais, ...) sont bien dans la même base de données dans les colonnes VARCHAR.

Je cherche quelque chose comme: 

  1. Si vous avez le chinois -> utilisez NVARCHAR
  2. Si vous avez l'allemand et l'arabe -> utilisez NVARCHAR

Qu'en est-il du classement du serveur/de la base de données?

Je ne souhaite pas utiliser toujours NVARCHAR comme suggéré ici Quelles sont les principales différences de performances entre les types de données varchar et nvarchar SQL Server?

63
Peter Gfader

La vraie raison pour laquelle vous souhaitez utiliser NVARCHAR est lorsque vous avez différent langues dans la même colonne, vous devez adresser les colonnes dans T-SQL sans décodage, vous souhaitez pouvoir afficher les données "de manière native" dans SSMS. , ou vous voulez normaliser sur Unicode.

Si vous traitez la base de données comme un stockage idiote, il est parfaitement possible de stocker des chaînes larges et des codages différents (même de longueur variable) dans VARCHAR (par exemple, UTF-8). Le problème survient lorsque vous essayez d’encoder et de décoder, en particulier si la page de code est différente pour différentes lignes. Cela signifie également que SQL Server ne sera pas en mesure de traiter facilement les données à des fins d'interrogation dans T-SQL sur des colonnes codées (de manière variable).

L'utilisation de NVARCHAR évite tout cela.

Je recommanderais NVARCHAR pour toute colonne contenant des données entrées par l'utilisateur, qui est relativement non contrainte.

Je recommanderais VARCHAR pour toute colonne constituant une clé naturelle (comme une plaque d'immatriculation de véhicule, un SSN, un numéro de série, un numéro de service, un numéro de commande, un indicatif d'aéroport, etc.) qui est généralement définie et limitée par une norme, une législation ou une convention. VARCHAR également pour les entrées entrées par l'utilisateur et très contraignantes (comme un numéro de téléphone) ou un code (ACTIF/FERMÉ, Y/N, M/F, M/S/D/W, etc.). Il n'y a absolument aucune raison d'utiliser NVARCHAR pour ceux-là.

Donc, pour une règle simple:

VARCHAR lorsqu'il est garanti d'être contraint NVARCHAR sinon

107
Cade Roux

Vous devez utiliser NVARCHAR chaque fois que vous devez stocker plusieurs langues. Je crois que vous devez l’utiliser pour les langues asiatiques mais ne me citez pas dessus.

Voici le problème si vous prenez le russe par exemple et que vous le stockez dans un varchar, tout ira bien tant que vous définissez la page de code correcte. Mais disons que vous utilisez une installation sql anglaise par défaut, les caractères russes ne seront pas gérés correctement. Si vous utilisiez NVARCHAR (), ils seraient gérés correctement.

Modifier

Ok, laissez-moi citer _ MSDN et Maybee était spécifique mais vous ne voulez pas stocker plus d'une page de code dans une colonne varcar, alors que vous ne devriez pas

Lorsque vous traitez avec des données texte, c’est stocké dans le caractère, varchar, varchar (max) ou type de données texte, le limitation la plus importante à prendre en compte est-ce seulement l'information d'un seul La page de code peut être validée par le système. (Vous pouvez stocker des données à partir de plusieurs pages de code , Mais ce n'est pas recommandé ) La page de code utilisée exactement pour valider et stocker les données dépend sur la collation de la colonne. Si un le classement au niveau de la colonne n'a pas été défini, le classement de la base de données est utilisé. Pour déterminer la page de code qui est utilisé pour une colonne donnée, vous peut utiliser le COLLATIONPROPERTY fonction, comme indiqué ci-dessous exemples de code:

En voici d'autres:

Cet exemple illustre le fait que de nombreux lieux, tels que Georgian et Hindi, n'ont pas de pages de code, car ils sont des classements Unicode uniquement. Ceux les collations ne sont pas appropriées pour les colonnes qui utilisent char, varchar ou type de données texte

Il faut donc que le géorgien ou l'hindi soit stocké sous nvarchar. L'arabe est aussi un problème:

Un autre problème que vous pourriez rencontrer est l'incapacité de stocker des données quand pas tous les personnages que vous souhaitez support sont contenus dans le code page. Dans de nombreux cas, Windows considère une page de code particulière doit être une page de code "meilleur fit", ce qui signifie qu'il existe aucune garantie que vous puissiez compter sur le page de code pour gérer tout le texte; il est simplement le meilleur disponible. Un Un exemple en est le script arabe: il prend en charge un large éventail de langues, y compris les Baloutchis, les Berbères, les Farsis, Cachemire, Kazakh, Kirghiz, Pashto, Sindhi, Uighur, Ourdou et plus encore. Tous ces langues ont additionnel caractères autres que ceux de l'arabe langage défini dans le code Windows page 1256. Si vous essayez de stocker ces caractères supplémentaires dans un colonne non-Unicode contenant l'arabe collation, les personnages sont converti en points d'interrogation.

Il convient de garder à l’esprit lorsque vous utilisez Unicode, même si vous pouvez stocker différentes langues dans une seule colonne, vous ne pouvez trier qu’en utilisant un seul classement. Certaines langues utilisent des caractères latins mais ne se classent pas comme les autres langues latines. Accents en est un bon exemple. Je ne peux pas le rappeler, mais il y avait une langue d’Europe de l’Est dont le Y ne ressemblait pas au Y anglais. Ensuite, il ya le ch espagnol qui devrait être trié après h.

Dans l’ensemble, vous avez tous les problèmes que vous devez résoudre en matière d’internalisation. À mon avis, il est plus facile d’utiliser des caractères Unicode dès le départ, d’éviter les conversions supplémentaires et de prendre l’espace. D'où ma déclaration plus tôt.

10
JoshBerke

Le grec aurait besoin de UTF-8 sur les types de colonne N: αβγ;)

3
cherouvim

Josh dit: ".... Il convient de garder à l'esprit lorsque vous utilisez Unicode, même si vous pouvez stocker différentes langues dans une seule colonne, vous ne pouvez les trier qu'avec un seul classement. Certaines langues utilisent des caractères latins, mais Les accents en sont un bon exemple, je ne peux pas me souvenir de cet exemple, mais il y avait une langue d’Europe de l’Est dont le Y ne ressemblait pas au Y anglais. être trié après h. "

Je suis un locuteur espagnol et "ch" n'est pas une lettre mais deux "c" et "h" et l'alphabet espagnol est similaire à: Abcdefghijklmn - opqrstuvwxyz Nous n'attendons pas "ch" après " h "mais" i " L’alphabet est le même qu’en anglais à l’exception du ñ ou en HTML" & ntilde; "

Alex

2
Alex

TL; DR;
Unicode - (nchar, nvarchar et ntext)
Non-unicode - (car, varchar et text).

De MSDN

Les classements dans SQL Server fournissent les règles de tri, la casse et l'accent propriétés de sensibilité pour vos données. Les collations utilisées avec Les types de données caractères tels que char et varchar dictent la page de code et les caractères correspondants pouvant être représentés pour ces données type.

En supposant que vous utilisez le classement SQL par défaut SQL_Latin1_General_CP1_CI_AS, le script suivant doit afficher tous les symboles que vous pouvez adapter à VARCHAR, car il utilise un octet pour stocker un caractère (256 au total) si vous ne le voyez pas dans la liste imprimée - vous avez NVARCHAR

declare @i int = 0;
while (@i < 256)
begin
print cast(@i as varchar(3)) + '  '+  char(@i)  collate SQL_Latin1_General_CP1_CI_AS 
print cast(@i as varchar(3)) + '  '+ char(@i)  collate Japanese_90_CI_AS  
set @i = @i+1;
end

Si vous modifiez la collation en japonais, vous remarquerez que toutes les lettres européennes étranges sont devenues normales et certains symboles, des marques ?.

Unicode est une norme pour mapper des points de code sur des caractères. Parce que il est conçu pour couvrir tous les caractères de toutes les langues du monde, il n’est pas nécessaire que différentes pages de code traitent différentes ensembles de caractères. Si vous stockez des données de caractères qui reflètent plusieurs langues, utilisez toujours les types de données Unicode (nchar, nvarchar et ntext) au lieu des types de données non Unicode (char, varchar et text).

Sinon, votre tri ira bizarre.

0
Matas Vaitkevicius