Le Support UTF-8, SQL Server 2012 et les UTF8String UDT
Des recherches sur le pro et con de SQL Server VARCHAR vs NVARCHAR pour mon application, j'en suis venu à la réalisation que l'idéal serait si SQL Server prise en charge de l'utf-8 en natif. Plusieurs postes d'indiquer qu'il n'a pas, par exemple:
Est de type VARCHAR totalement des années 1990?
Cependant puis je suis tombé sur cet article dans la documentation MSDN pour SQL Server 2012 qui montre comment créer un UTF8String type de données utilisateur:
http://msdn.microsoft.com/en-us/library/ff877964(v=sql.110).aspx
Il semble que UDT permettrait de l'espace (mémoire, disque) pour les prestations de 8 bits par caractère, tout en étant suffisamment souple pour stocker n'importe quelle chaîne de caractères qui peut être représenté en UTF-8. Est-ce exact? Existe-il des inconvénients à cette stratégie (par exemple, le coût de l'exécution du code managé pour chaque ligne, ...)?
OriginalL'auteur Eric J. | 2012-01-24
Vous devez vous connecter pour publier un commentaire.
Créer un Type Défini par l'Utilisateur via SQLCLR est pas, en quelque sorte, va vous obtenir un remplacement de tout type natif. Il est très pratique pour la création de quelque chose à gérer de données spécialisées. Mais les cordes, même d'un autre encodage, sont loin d'être spécialisé. Aller dans cette voie pour votre chaîne de données permettrait de détruire tout montant de la facilité d'utilisation de votre système, pour ne pas mentionner la performance que vous ne serait pas en mesure d'utiliser tout intégré dans les fonctions de chaîne.
Si vous étiez en mesure de sauver quoi que ce soit sur l'espace disque, ces gains seraient effacés par ce que vous ne voudriez pas perdre en performance globale. Le stockage d'un type défini par l'utilisateur est effectuée par sérialisation d'un
VARBINARY
. Ainsi afin de faire tout de comparaison de chaîne OU de tri, en dehors d'un "binaire" /"ordinal" comparaison, vous devrez convertir toutes les autres valeurs, un par un, de retour à l'UTF-8 pour ensuite faire la comparaison de chaîne qui peut tenir compte des différences linguistiques. Et que la conversion devra être effectué au sein de l'UDT. Cela signifie que, comme le type de données XML, vous devez créer l'UDT pour contenir une valeur particulière, et d'exposer une méthode de type défini par l'utilisateur à accepter un paramètre de chaîne pour faire la comparaison (c'est à direUtf8String.Compare(alias.field1)
ou, si la définition d'un opérateur pour le type, puisUtf8string1 = Utf8string2
et ont la=
opérateur d'obtenir la chaîne de caractères dans le codage UTF-8, puis effectuer lesCompareInfo.Compare()
).Outre les considérations ci-dessus, vous devez également considérer que la transmission des valeurs d'avant en arrière à travers la SQLCLR API a un coût, en particulier lors de l'utilisation de
NVARCHAR(MAX)
ouVARBINARY(MAX)
par opposition àNVARCHAR(1 - 4000)
etVARBINARY(1 - 4000)
respectivement (merci de ne pas confondre cette distinction implique rien sur l'utilisation deSqlChars
/SqlBytes
vsSqlString
/SqlBinary
).Enfin (au moins en termes d'utilisation d'un type défini par l'utilisateur), s'il vous plaît ne pas regarder au-delà du fait que le type défini par l'utilisateur d'être renseigné sur est exemple de code. Les seuls tests de noter est purement fonctionnelle, rien autour de l'évolutivité ou de "leçons apprises après avoir travaillé avec ce pour un an". Le test fonctionnel code est montré ici, à la suite de CodePlex page et doit être regardé avant de procéder à cette décision car il donne un sens de la façon dont vous auriez besoin pour écrire vos requêtes afin d'interagir avec elle (ce qui est très bien pour un champ ou deux, mais pas pour la plupart /tous les champs de type chaîne):
http://msftengprodsamples.codeplex.com/SourceControl/latest#Kilimanjaro_Trunk/Programmability/CLR/UTF8String/Scripts/Test.sql
Étant donné le nombre de colonnes calculées persistantes et les index ajouté, était tout espace vraiment sauvé? 😉
Où l'espace (disque, mémoire, etc) est la préoccupation, vous avez trois options:
Si vous utilisez SQL Server 2008 ou plus récent, et sont sur Enterprise Edition, vous pouvez activer La Compression De Données. La Compression de données peut (mais ne pas "toujours") compresser les données Unicode dans
NCHAR
etNVARCHAR
champs. Les facteurs déterminants sont:NCHAR(1 - 4000)
etNVARCHAR(1 - 4000)
utiliser le Schéma de Compression Standard Unicode, mais seulement à partir de SQL Server 2008 R2, ET seulement DANS la LIGNE de données, pas de DÉBORDEMENT! Cela semble être mieux que l'ordinaire de lignes /PAGE algorithme de compression.NVARCHAR(MAX)
etXML
(et je suppose aussiVARBINARY(MAX)
,TEXT
, etNTEXT
) à des données EN LIGNE (pas de ligne de MÉTIER ou de DÉBORDEMENT de pages) peut être au moins la PAGE comprimé, et peut-être aussi LIGNE comprimé (pas sûr à propos de cette dernière).Si vous utilisez une version antérieure à la version 2008 ou non sur Enterprise Edition, vous pouvez avoir deux champs: l'un
VARCHAR
et unNVARCHAR
. Par exemple, disons que vous êtes stocker les Url qui sont pour la plupart de la base de caractères ASCII (valeurs de 0 - 127) et donc de s'insérer dansVARCHAR
, mais ont parfois des caractères Unicode. Votre schéma peut inclure les éléments suivants 3 champs:Dans ce modèle vous seulement SÉLECTIONNER à partir de la
[URL]
colonne calculée. Pour l'insertion et la mise à jour, vous de déterminer qui est le champ par voir si la conversion en modifie la valeur entrante, qui doit être deNVARCHAR
type:Si vous avez des champs qui ne devrait jamais avoir des personnages qui s'inscrivent dans une particulier de la Page de Code d'un jeu de caractères ASCII Étendu, alors il suffit d'utiliser
VARCHAR
.P. S. Juste pour avoir cette a déclaré pour plus de clarté: la nouvelle
_SC
les Classements qui ont été introduites dans SQL Server 2012, il vous suffit de permettre:Mais, même sans la nouvelle
_SC
Classements, vous pouvez toujours stocker n'importe quel caractère Unicode dans un fichier XML ouN
de préfixe de type, et de les récupérer sans perte de données. Cependant, lors de l'utilisation de l'ancienne Classements (c'est à dire pas de numéro de version dans le nom), tous les Caractères Supplémentaires assimiler les uns aux autres. Vous devez utiliser le_90
et_100
Classements qui, à moins de vous obtenir le binaire /code de point de comparaisons et de tri; ils ne peuvent pas prendre en compte les règles linguistiques, car ils n'ont pas particulièrement les mappages des Caractères Supplémentaires (et donc n'ont aucun poids ou des règles de normalisation).Essayez ce qui suit:
Dans un DB d'avoir un classement par défaut se terminant en
_SC
, seule la premièreIF
retournera un ensemble de résultats, et les "Produits" champ affiche les caractères correctement.Mais, si la DB n'ont pas de classement par défaut se terminant en
_SC
, et le classement n'est pas une_90
ou_100
série de classement, puis les deux premièresIF
déclarations de retour des ensembles de résultats dans laquelle le "Généré" champ sera de retourNULL
, et la "Littérale" du champ s'affiche correctement.Pour les données Unicode, le Classement n'a aucune incidence sur le stockage physique.
Mise à JOUR 2018-10-02
Alors que ce n'est pas une option viable encore, SQL Server 2019 introduit la prise en charge native pour l'UTF-8 dans
VARCHAR
/CHAR
les types de données. Il y a actuellement trop de bugs avec elle pour lui pour être utilisés, mais s'ils sont fixes, alors c'est une option pour certains scénarios. Veuillez voir mon post, "Natif de l'UTF-8 est pris en charge dans SQL Server 2019: Sauveur ou Faux Prophète?", pour une analyse détaillée de cette nouvelle fonctionnalité.NVARCHAR(1 - 4000)
veux dire?Cela signifie choisir un nombre entre 1 et 4000.
Désolé si je n'ai pas été clair à ce sujet. Fondamentalement, ce que Aaron a dit: c'est juste ma façon d'indiquer une non-
MAX
type NVARCHAR, qui ne peut être dans la gamme de 1 - 4000.OriginalL'auteur Solomon Rutzky