Quand devons-nous utiliser NVARCHAR / NCHAR au lieu de VARCHAR / CHAR dans SQL Server?
-
03-07-2019 - |
Question
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:
- Si vous avez le chinois - > utiliser NVARCHAR
- Si vous avez l'allemand et l'arabe - > utiliser NVARCHAR
Qu'en est-il du classement du serveur / de la base de données?
Je ne veux pas utiliser toujours NVARCHAR comme suggéré ici Quelles sont les principales différences de performances entre les types de données SQL Server varchar et nvarchar?
La solution
Si vous souhaitez utiliser NVARCHAR, c’est lorsque vous avez différentes langues dans la même colonne, que vous devez adresser les colonnes dans T-SQL sans décodage, vous souhaitez pouvoir afficher les données " nativement " dans SSMS ou si vous souhaitez normaliser l’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 à toutes les colonnes contenant des données saisies par l'utilisateur et relativement peu contraignantes.
Je recommanderais VARCHAR pour toute colonne constituant une clé naturelle (plaque d'immatriculation d'un véhicule, SSN, numéro de série, numéro de service, numéro de commande, indicatif d'aéroport, etc.) généralement définie et limitée par une norme, une législation ou des règles. 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’ya aucune raison d’utiliser NVARCHAR pour ceux-là.
Donc, pour une règle simple:
VARCHAR lorsqu'il est garanti d'être contraint NVARCHAR autrement
Autres conseils
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 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
Bien, laissez-moi citer MSDN et Maybee j'étais spécifique, mais vous ne souhaitez pas stocker plus d'une page de code dans une colonne varcar, alors que vous ne le devriez pas
Lorsque vous traitez avec des données texte qui sont stocké dans le caractère, varchar, varchar (max), ou type de données texte, le limite la plus importante à considérer 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 exacte utilisée 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é dans la suite exemples de code:
En voici d'autres:
Cet exemple illustre le fait que de nombreux lieux, tels que le géorgien et Hindi, n'ont pas de pages de code, car ils sont des classements Unicode uniquement. Ceux les collations ne conviennent pas pour les colonnes qui utilisent char, varchar ou type de données texte
Ainsi, le géorgien ou l'hindi doit vraiment être 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 le support sont contenus dans le code page. Dans de nombreux cas, Windows considère une page de code particulière pour être un "meilleur" ajustement " page de code, ce qui signifie qu'il y a aucune garantie que vous pouvez 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 baloutches, les berbères, le farsi, Cachemire, Kazakh, Kirghiz, Pashto, Sindhi, Uighur, Ourdou, et plus encore. Tous ces langues ont plus caractères au-delà de ceux de l'arabe langage défini dans le code Windows page 1256. Si vous essayez de stocker ces personnages supplémentaires dans un colonne non-Unicode qui a l'arabe collation, les personnages sont convertis 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 n’était pas semblable au Y anglais. / p>
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 antérieure.
Le grec aurait besoin de UTF-8 sur N types de colonnes: aß?;)
Josh dit: ".... Ce que vous devez garder à l'esprit lorsque vous utilisez Unicode, même si vous pouvez stocker différentes langues dans une seule colonne, vous ne pouvez effectuer un tri qu'avec un seul classement. Certaines langues utilisent des caractères latins mais ne se classent pas comme les autres langues latines. Accents est un bon exemple de cela. Je ne peux pas me rappeler cet exemple, mais il y avait une langue d'Europe de l'Est dont le Y n'était pas un anglais comme le Y. Ensuite, il y a le ch espagnol qui doit être trié après h. & Quot. ;
Je suis un locuteur espagnol natif et "ch". n’est pas une lettre mais deux "c" et " h " et l'alphabet espagnol est comme: abcdefghijklmn ñ opqrstuvwxyz Nous n'attendons pas de & ch; ch " après " h " mais " i " L’alphabet est le même qu’en anglais à l’exception du ñ ou en HTML "& amp; ntilde;"
Alex
TL; DR;
Unicode - (nchar, nvarchar et ntext)
Non-Unicode - (car, varchar et text).
Les classements dans SQL Server fournissent des règles de tri, des cas et des accents 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 qui peuvent ê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 alors afficher tous les symboles que vous pouvez adapter à VARCHAR
car il utilise un octet pour stocker un caractère ( Si vous ne le voyez pas sur la liste imprimée, vous avez besoin de 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, en ?
.
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 personnage qui reflètent plusieurs langues, utilisez toujours des 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.