83 votes

Quand doit-on utiliser NVARCHAR/NCHAR au lieu de VARCHAR/CHAR dans SQL Server ?

Existe-t-il une règle selon laquelle 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 des colonnes VARCHAR.

Je cherche quelque chose comme :

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

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

Je ne veux pas utiliser toujours NVARCHAR comme suggéré ici. Quelles sont les principales différences de performance entre les types de données varchar et nvarchar du serveur SQL ?

0 votes

Les deux questions les plus votées sont mauvais . Cela n'a rien à voir avec le fait de "stocker des langues différentes/multiples". Vous pouvez prendre en charge les caractères espagnols comme ñ et anglais, avec juste un varchar commun.

0 votes

Je viens de poster une réponse expliquant et fournissant également une approche actualisée sur la façon de traiter ce problème.

126voto

Cade Roux Points 53870

La vraie raison pour laquelle vous voulez utiliser NVARCHAR est lorsque vous avez différents dans la même colonne, vous avez besoin d'adresser les colonnes en T-SQL sans décodage, vous voulez être capable de voir les données "nativement" dans SSMS, ou vous voulez standardiser sur Unicode.

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

L'utilisation de NVARCHAR permet d'éviter tout cela.

Je recommanderais NVARCHAR pour toute colonne qui contiendra des données saisies par l'utilisateur et qui est relativement peu contraignante.

Je recommanderais VARCHAR pour toute colonne qui est une clé naturelle (comme une plaque d'immatriculation de véhicule, un SSN, un numéro de série, une étiquette 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 pour les données saisies par l'utilisateur et très limitées (comme un numéro de téléphone) ou un code (ACTIF/FERMÉ, O/N, H/F, M/S/D/W, etc.). Il n'y a absolument aucune raison d'utiliser NVARCHAR pour ces éléments.

Donc pour une règle simple :

VARCHAR lorsque la contrainte est garantie NVARCHAR sinon

6 votes

Il convient de noter que "différentes langues" ne signifie pas seulement que différentes lignes peuvent contenir des valeurs provenant de différentes langues. Cela signifie également que si la collation par défaut de la base de données (c'est-à-dire la locale de la machine serveur) est différente de la locale de n'importe quel ordinateur client, par exemple si la machine serveur est réglée sur en-US mais mon PC est réglé sur fr-US .

0 votes

@IanBoyd En général, la collation va être très problématique lorsque l'on mélange des langues dans une colonne et que l'on retourne des éléments dans plusieurs langues dans un seul ensemble et que l'on utilise cette collation pour le classement. La collation peut également avoir un effet sur les caractères qui sont combinés pour être traités comme un seul (dz et ly hongrois) : sqlservercentral.com/Forums/Topic19439-9-1.aspx stackoverflow.com/questions/7207590/ - nvarchar ne va pas résoudre ce problème.

3 votes

Un certain nombre de pays asiatiques (dont la Chine) utilisent des logogrammes dans leurs plaques d'immatriculation. À moins d'être sûr à 100 % que votre programme ne traitera jamais ce type de données, il est préférable d'utiliser nvarchar pour les plaques d'immatriculation. Et oui, cela inclut des choses comme l'enregistrement des infractions au code de la route, les parkings et les méthodes de transport des véhicules. Il est tout à fait possible qu'un Chinois prenne un ferry ou même se rende en voiture dans votre pays et gare sa voiture dans votre garage.

40voto

Vitox Points 2168

Les deux réponses les plus votées sont fausses. Cela n'a rien à voir avec "stocker différentes/multiples langues". Vous pouvez prendre en charge les caractères espagnols comme <code>ñ</code> et l'anglais, avec juste le commun <code>varchar</code> et <code>Latin1_General_CI_AS</code> <code>COLLATION</code> par exemple

Version courte
Vous devez utiliser NVARCHAR / NCHAR chaque fois que le ENCODING qui est déterminé par COLLATION du champ, ne supporte pas les caractères nécessaires.
De plus, en fonction de la version du serveur SQL, vous pouvez utiliser des fonctions spécifiques de COLLATIONs comme Latin1_General_100_CI_AS_SC_UTF8 qui est disponible depuis SQL Server 2019. La définition de cette collation sur un VARCHAR (ou toute la table/base de données), utilisera la fonction UTF-8 ENCODING pour le stockage et le traitement des données de ce champ, ce qui permet de prendre entièrement en charge UNICODE les caractères, et donc toutes les langues qu'il englobe.

Pour COMPRENDRE COMPLÈTEMENT :
Pour bien comprendre ce que je vais expliquer, il est obligatoire d'avoir les concepts de <code>UNICODE</code> , <code>ENCODING</code> et <code>COLLATION</code> tout est extrêmement clair dans votre tête. Si ce n'est pas le cas, jetez d'abord un coup d'œil ci-dessous à mon explication humble et simplifiée de la section "Qu'est-ce que l'UNICODE, l'ENCODING, la COLLATION et l'UTF-8, et comment ils sont liés" et aux liens de documentation fournis. En outre, tout ce que je dis ici est spécifique à <code>Microsoft SQL Server</code> et la manière dont il stocke et traite les données dans <code>char</code> / <code>nchar</code> et <code>varchar</code> / <code>nvarchar</code> champs.

Disons que nous voulons stocker un texte particulier dans notre base de données MSSQL Server. Il peut s'agir d'un commentaire Instagram du type "J'aime stackoverflow !

12voto

JoshBerke Points 34238

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 cite pas.

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

Editar

Ok, laissez-moi vous citer MSDN et peut-être que j'étais trop spécifique mais vous ne voulez pas stocker plus d'une page de code dans une colonne de varcar, bien que vous puissiez le faire, vous ne devriez pas le faire.

Lorsque vous traitez des données textuelles qui sont stockées dans les formats char, varchar varchar(max), ou text, la limitation la plus importante limitation la plus importante à prendre en compte est que seules les informations d'une seule page de code peuvent être validées par le système. (Vous pouvez stocker des données provenant de plusieurs pages de codes, mais cela n'est pas recommandé). La page de codes exacte utilisée pour valider et stocker les données dépend de la collation de la colonne. Si une collation au niveau de la colonne n'a pas été définie, la collation de la base de données est utilisée. Pour déterminer la page de code qui est utilisée pour une colonne donnée, vous pouvez utiliser la fonction COLLATIONPROPERTY comme le montrent les exemples de code suivants exemples de code suivants :

En voici d'autres :

Cet exemple illustre le fait que de nombreux locaux, tels que le géorgien et le l'hindi, n'ont pas de pages de code, car elles sont sont des collations Unicode uniquement. Ces collations ne sont pas appropriées pour les colonnes qui utilisent le type de données char, varchar ou type de données texte

Ainsi, le géorgien ou l'hindi doivent vraiment être stockés sous forme de nvarchar. L'arabe pose également un problème :

Un autre problème que vous pouvez rencontrer est l'impossibilité de stocker des données lorsque pas tous les caractères que vous souhaitez sont contenus dans la page de code. page. Dans de nombreux cas, Windows considère une page de codes particulière comme étant la "meilleure page de code "best fit", ce qui signifie qu'il n'y a garantie que vous pouvez compter sur cette page page de code pour traiter tout le texte ; il s'agit simplement la meilleure page de code disponible. Un exemple exemple de ceci est le script arabe : il supporte un large éventail de langues, dont le baloutche, le berbère, le farsi, Cachemiri, Kazakh, Kirghiz, Pashto, le sindhi, l'ouïgour, l'ourdou, etc. Toutes ces ces langues ont des caractères supplémentaires caractères supplémentaires en plus de ceux de la langue arabe tels que définis dans le code Windows page 1256 du code Windows. Si vous essayez de stocker ces caractères supplémentaires dans une colonne non-Unicode qui a la collation arabe arabe, ces caractères sont convertis en points d'interrogation.

Il faut garder à l'esprit que si vous utilisez l'Unicode, bien que vous puissiez stocker différentes langues dans une seule colonne, vous ne pouvez trier qu'en utilisant une seule collation. Il existe des langues qui utilisent des caractères latins mais qui ne sont pas triées comme les autres langues latines. Les accents en sont un bon exemple, je ne me souviens plus de l'exemple mais il y avait une langue d'Europe de l'Est dont le Y n'était pas trié comme le Y anglais. Il y a aussi le ch espagnol que les utilisateurs espagnols considèrent comme trié après le h.

Dans l'ensemble, avec tous les problèmes que l'on rencontre lorsqu'on traite de l'internalisation. Je pense qu'il est plus facile d'utiliser les caractères Unicode dès le départ, d'éviter les conversions supplémentaires et de prendre le risque de perdre de l'espace. D'où ma déclaration précédente.

4 votes

>>Il faut utiliser NVARCHAR chaque fois que l'on doit stocker plusieurs langues. L'allemand, l'italien et l'anglais ont leur place dans la même table avec des colonnes VARCHAR. Veuillez être plus précis

0 votes

Voir sqlservercentral.com/Forums/Topic19439-9-1.aspx et stackoverflow.com/questions/7207590/ pour des exemples avec dz et ly en hongrois.

5voto

cherouvim Points 18550

Le grec aurait besoin d'UTF-8 sur N types de colonnes : αβγ ;)

2voto

Alex Points 21

Josh dit : "....Une chose à garder à l'esprit lorsque vous utilisez Unicode : bien que vous puissiez stocker différentes langues dans une seule colonne, vous ne pouvez trier qu'en utilisant une seule collation. Il existe des langues qui utilisent des caractères latins mais qui ne sont pas triées comme les autres langues latines. Les accents en sont un bon exemple, je ne me souviens plus de l'exemple mais il y avait une langue d'Europe de l'Est dont le Y n'était pas trié comme le Y anglais. Il y a aussi le ch espagnol que les utilisateurs espagnols considèrent comme devant être trié après le h."

Je suis de langue maternelle espagnole et "ch" n'est pas une lettre mais deux "c" et "h" et l'alphabet espagnol est comme : abcdefghijklmn ñ opqrstuvwxyz Nous n'attendons pas "ch" après "h" mais "i". L'alphabet est le même qu'en anglais sauf pour le ñ ou en HTML "&ntilde ;".

Alex

0 votes

Bonjour Alex, avez-vous déjà stocké différentes langues dans une seule colonne ? Nous avions différentes colonnes pour différentes langues dans une seule table.

0 votes

Ils font probablement référence au tchèque. Nous avons "ch" entre "h" et "i" et c'est une lettre distincte de l'alphabet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X