web-dev-qa-db-fra.com

À quoi sert vraiment le type de données de caractère national SQL (NCHAR)?

Ainsi que CHAR(CHARACTER) et VARCHAR(CHARACTER VARYING), SQL propose un NCHAR(NATIONAL CHARACTER) et NVARCHAR(NATIONAL CHARACTER VARYING) type. Dans certaines bases de données, c'est le meilleur type de données à utiliser pour les chaînes de caractères (non binaires):

  • Dans SQL Server, NCHAR est stocké au format UTF-16LE et est le seul moyen de stocker de manière fiable des caractères non ASCII, CHAR étant une page de code à un octet uniquement;

  • Dans Oracle, NVARCHAR peut être stocké au format UTF-16 ou UTF-8 plutôt qu'à un classement sur un octet;

  • Mais dans MySQL, NVARCHAR est VARCHAR, donc cela ne fait aucune différence, les deux types peuvent être stockés avec UTF-8 ou tout autre classement.

Alors, qu'est-ce que NATIONAL signifie réellement conceptuellement, le cas échéant? Les documents des fournisseurs ne vous renseignent que sur les jeux de caractères utilisés par leurs propres SGBD, plutôt que sur la justification réelle. Pendant ce temps, la norme SQL92 explique la fonctionnalité encore moins utilement, indiquant seulement que NATIONAL CHARACTER est stocké dans un jeu de caractères défini par l'implémentation. Par opposition à un simple CHARACTER, qui est stocké dans un jeu de caractères défini par l'implémentation. Ce qui pourrait être un autre jeu de caractères défini par l'implémentation. Ou pas.

Merci, ANSI. Thansi.

Doit-on utiliser NVARCHAR pour tous les besoins de stockage de caractères (non binaires)? Existe-t-il des SGBD actuellement populaires dans lesquels il fera quelque chose de indésirable, ou qui ne reconnaissent tout simplement pas le mot clé (ou N'' littéraux)?

50
bobince

"NATIONAL" dans ce cas signifie des caractères spécifiques à différentes nationalités. Les langues d'Extrême-Orient ont surtout tellement de caractères qu'un octet n'est pas assez d'espace pour les distinguer tous. Donc, si vous avez une application uniquement en anglais (ascii) ou un champ uniquement en anglais, vous pouvez vous en sortir en utilisant les anciens types CHAR et VARCHAR, qui n'autorisent qu'un octet par caractère.

Cela dit, la plupart du temps, vous devez utiliser NCHAR/NVARCHAR. Même si vous ne pensez pas avoir besoin de prendre en charge (ou potentiellement prendre en charge) plusieurs langues dans vos données, même les applications uniquement en anglais doivent être capables de gérer de manière sensible les attaques de sécurité en utilisant des caractères en langue étrangère.

À mon avis, le seul endroit où les anciens types CHAR/VARCHAR sont encore préférés est pour les codes internes et les données ascii uniquement référencés fréquemment sur des plates-formes comme Sql Server qui prennent en charge la distinction - des données qui seraient l'équivalent d'un enum dans un langage client comme C++ ou C #.

14
Joel Coehoorn

Pendant ce temps, la norme SQL92 explique la fonctionnalité de manière encore moins utile, indiquant uniquement que NATIONAL CHARACTER est stocké dans un jeu de caractères défini par l'implémentation. Par opposition à un simple CHARACTER, qui est stocké dans un jeu de caractères défini par l'implémentation. Ce qui pourrait être un autre jeu de caractères défini par l'implémentation. Ou pas.

Par coïncidence, c'est la même "distinction" que la norme C++ fait entre char et wchar_t. Une relique de l'âge des ténèbres de l'encodage des caractères lorsque chaque combinaison langue/système d'exploitation a son propre jeu de caractères.

Faut-il utiliser NVARCHAR à toutes fins de stockage de caractères (non binaires)?

Peu importe que le type déclaré de votre colonne soit VARCHAR ou NVARCHAR. Mais il est important d'utiliser Unicode (que ce soit UTF-8, UTF-16 ou UTF-32) à toutes fins de stockage de caractères.

Existe-t-il des SGBD actuellement populaires dans lesquels il fera quelque chose de indésirable

Oui: dans MS SQL Server, l'utilisation de NCHAR fait que vos données (anglaises) occupent deux fois plus d'espace. Malheureusement, TF-8 n'est pas encore pris en charge .

4
dan04

Dans Oracle, le jeu de caractères de la base de données peut être un jeu de caractères multi-octets, vous pouvez donc y stocker toutes sortes de caractères ... mais vous devez comprendre et définir la longueur des colonnes de manière appropriée (en octets ou en caractères) .

NVARCHAR vous donne la possibilité d'avoir un jeu de caractères de base de données qui est un octet unique (ce qui réduit le risque de confusion entre les colonnes de taille BYTE ou CHARACTER) et d'utiliser NVARCHAR comme multi-octet. Voir ici .

Étant donné que je travaille principalement avec des données en anglais, je choisirais un jeu de caractères multi-octets (UTF-8 principalement) comme jeu de caractères de la base de données et j'ignorerais NVARCHAR. Si j'ai hérité d'une ancienne base de données qui était dans un jeu de caractères à un octet et était trop grande pour être convertie, je peux utiliser NVARCHAR. Mais je préfère ne pas le faire.

3
Gary Myers