Question

Alors que Options de recherche Pour le stockage principalement de l'anglais mais non des données dans une base de données SQL Server qui peut potentiellement être assez grande, je me penche vers le stockage de la plupart des données de chaîne comme UTF-8 codé.

Cependant, Microsoft a choisi UCS-2 pour des raisons que je ne comprends pas parfaitement, ce qui me fait deviner cette pension. La documentation de SQL Server 2012 montre comment créer un UDT UTF-8, mais la décision pour UCS-2 imprègne vraisemblablement SQL Server.

Wikipédia (Ce qui note de manière intéressante que UCS-2 est obsolète en faveur de l'UTF-16) note que l'UTF-8 est un jeu de caractères variable capable d'encoder n'importe quel point de données Unicode et qu'il provides the de facto standard encoding for interchange of Unicode text. Ainsi, il semble que tout caractère Unicode peut être représenté dans UTF-8, et comme la plupart du texte sera anglais, la représentation sera presque deux fois plus compacte qu'avec UCS-2 (je sais que le disque est "bon marché", mais le cache de disque n'est pas «T, et la mémoire n'est pas en comparaison avec les tailles de données avec lesquelles je suis affaire. De nombreuses opérations se dégradent de façon exponentielle lorsque l'ensemble de travail est plus grand que la RAM disponible).

Quels problèmes puis-je rencontrer en nageant le flux UCS-2?

Était-ce utile?

La solution

Stockage principalement de l'anglais mais non des données dans une base de données SQL Server qui peut potentiellement être assez grande, je me penche vers le stockage de la plupart des données de chaîne comme UTF-8 codé.

Contrairement à certains autres SGBDR qui permettent de choisir un encodage, SQL Server stocke les données Unicode seulement Dans UTF-16 (Little Endian), et les données non Unicodes dans un codage 8 bits (ASCII étendu, DBCS ou EBCDIC) pour la page de code impliquée par la collation du champ.

Microsoft a choisi UCS-2 pour des raisons que je ne comprends pas complètement

Leur décision de choisir L'UCS-2 est suffisamment logique étant donné que l'UTF-16 a été introduit au milieu de 1996 et entièrement spécifié en 2000. Beaucoup d'autres systèmes l'utilisent (ou utilisé) (veuillez également voir: https://en.wikipedia.org/wiki/UTF-16#usage). Leur décision de Continuez avec cela peut être plus discutable, bien que cela soit probablement dû au fait que Windows et .NET sont UTF-16. La disposition physique des octets est la même entre UCS-2 et UTF-16, donc la mise à niveau des systèmes de UCS-2 pour prendre en charge l'UTF-16 devrait être purement fonctionnelle sans avoir besoin de modifier les données existantes.

La documentation de SQL Server 2012 montre comment créer un UDT UTF-8,

Um non. La création d'un type défini par l'utilisateur personnalisé via SQLCLR est ne pas, de quelque manière que ce soit, vous obtenez un remplacement de tout type natif. Il est très pratique de créer quelque chose pour gérer des données spécialisées. Mais les cordes, même d'un codage différent, sont loin d'être spécialisées. Suivre cette voie pour vos données de chaîne détruirait toute quantité de convivialité de votre système, sans parler des performances car vous ne pourriez pas utiliser n'importe quel Fonctions de chaîne intégrées. Si vous pouviez économiser quoi que ce soit sur l'espace disque, ces gains seraient effacés par ce que vous perdriez dans les performances globales. Le stockage d'un UDT se fait en le sérialisant à un VARBINARY. Donc pour faire n'importe quel Comparaison ou tri des chaînes, en dehors d'une comparaison "binaire" / "ordinale", vous devrez convertir toutes les autres valeurs, une par une, à UTF-8 pour ensuite effectuer la comparer la chaîne qui peut tenir compte des différences linguistiques.

De plus, cette "documentation" est vraiment juste un exemple de code / preuve de concept. Le code a été écrit en 2003 ( http://msftengprodsamples.codeplex.com/sourcecontrol/latest#kilimanjaro_trunk/programmability/clr/utf8string/cs/utf8string/utf8string.cs ) pour SQL Server 2005. J'ai vu un script pour tester les fonctionnalités, mais rien impliquant des performances.

Mais la décision pour UCS-2 imprègne vraisemblablement SQL Server.

Oui, beaucoup. Par défaut, la gestion des fonctions intégrées est uniquement pour UCS-2. Mais à partir de SQL Server 2012, vous pouvez les amener à gérer le jeu de caractères UTF-16 complet (enfin, à partir de Unicode version 5 ou 6, en fonction de votre système d'exploitation et de votre version du .NET) en utilisant l'une des collations qui a un nom se terminant _SC (c'est-à-dire des caractères supplémentaires).

Wikipedia ... note que UCS-2 est obsolète en faveur de l'UTF-16

Corriger. UTF-16 et UCS-2 utilisent tous deux des points de code de 2 octets. Mais UTF-16 utilise certains d'entre eux par paires (c.-à-d. Paires de substitution) pour cartographier des caractères supplémentaires. Les points de code utilisés pour ces paires sont réservés à cet effet dans UCS-2 et ne sont donc pas utilisés pour mapper à des symboles utilisables. C'est pourquoi vous pouvez stocker n'importe quel caractère Unicode dans SQL Server et il sera stocké et récupéré correctement.

Wikipedia ... note que l'UTF-8 est un jeu de caractères variable à largeur capable de coder tout point de données Unicode

Correct, bien que trompeur. Oui, UTF-8 est une largeur variable, mais l'UTF-16 est également une variable légèrement variable car tous les caractères supplémentaires sont composés de deux points de code à double octet. Par conséquent, UTF-16 utilise 2 ou 4 octets par symbole, bien que UCS-2 soit toujours de 2 octets. Mais ce n'est pas la partie trompeuse. Ce qui est trompeur, c'est l'implication que tout autre codage Unicode n'est pas capable d'encoder tous les autres points de code. Bien que l'UCS-2 puisse les maintenir mais ne pas les interpréter, UTF-16 et UTF-32 peuvent tous deux cartographier tous les points de code Unicode, tout comme UTF-8.

et qu'il [ed: UTF-8] fournit le codage standard de facto pour l'échange du texte Unicode.

Cela peut être vrai, mais il est entièrement hors de propos dans une perspective opérationnelle.

Il semble que tout caractère Unicode peut être représenté dans UTF-8

Encore une fois, c'est vrai, mais entièrement hors de propos, car UTF-16 et UTF-32 mappent également tous les points de code Unicode.

Étant donné que la plupart du texte sera anglais, la représentation sera presque deux fois plus compacte qu'avec UCS-2

Selon les circonstances, cela pourrait très bien être vrai, et vous avez raison de vous soucier d'une telle utilisation inutile. Cependant, comme je l'ai mentionné dans la question qui a conduit à celui-ci ( Prise en charge de l'UTF-8, SQL Server 2012 et l'UDT UTF8String ), vous avez quelques options pour atténuer la quantité d'espace gaspillée si la plupart des lignes peuvent s'adapter VARCHAR Pourtant, certains doivent être NVARCHAR. La meilleure option consiste à activer la compression des lignes ou la compression de pages (Enterprise Editon uniquement!). À partir de SQL Server 2008 R2, ils autorisent la non-max NVARCHAR Champs pour utiliser le "schéma de compression standard pour Unicode" qui est au moins aussi bon que UTF-8, et dans certains cas, il est encore mieux que UTF-8. NVARCHAR(MAX) Les champs ne peuvent pas utiliser cette compression fantaisie, mais leurs données dans les lignes peuvent bénéficier d'une compression régulière des lignes et / ou des pages. Veuillez consulter ce qui suit pour une description de cette compression et un graphique comparant les tailles de données pour: RAW UCS-2 / UTF-16, UTF-8 et UCS-2 / UTF-16 avec compression des données activées.

SQL Server 2008 R2 - Compression UCS2 Qu'est-ce qu'il y a - Impact sur les systèmes SAP

Veuillez également consulter la page MSDN pour Compression de données Pour plus de détails, car il y a certaines restrictions (au-delà de celles disponibles uniquement dans Enterprise Edition - mais mis à la disposition de tout Les éditions commençant par SQL Server 2016, SP1 !!) et certaines circonstances où la compression pourrait aggraver les choses.

Je sais que le disque est "bon marché"

La véracité de cette déclaration dépend de la façon dont on définit le "disque". Si vous parlez en termes de pièces de base que vous pouvez acheter sur l'étagère dans un magasin à utiliser dans votre bureau / ordinateur portable, bien sûr. Mais, si vous parlez en termes de stockage au niveau de l'entreprise qui sera utilisé pour vos systèmes de production, vous amusez-vous à expliquer à quiconque contrôle le budget qu'ils ne devraient pas rejeter le SAN à million de dollars que vous voulez car c'est "bon marché ";-).

Quels problèmes puis-je rencontrer en nageant le flux UCS-2?

Aucun auquel je peux penser. Eh bien, tant que vous ne suivez aucun conseil horrible pour faire quelque chose comme la mise en œuvre de cet UDT, ou la conversion de toutes les cordes en VARBINARY, ou en utilisant NVARCHAR(MAX) pour tous les champs de cordes ;-). Mais de toutes les choses qui pourraient vous inquiéter, SQL Server utilisant UCS-2 / UTF-16 ne devrait pas en faire partie.

Mais, si pour une raison quelconque, ce problème d'aucune prise en charge native pour UTF-8 est super important, vous devrez peut-être trouver un autre SGBDR à utiliser qui permet UTF-8.


Mise à jour 2018-10-02

Bien que ce ne soit pas encore une option viable, SQL Server 2019 présente la prise en charge native pour UTF-8 en VARCHAR / CHAR Types de données. Il y a actuellement trop de bugs avec lui pour qu'il soit utilisé, mais s'ils sont corrigés, alors c'est une option pour quelques scénarios. S'il vous plaît voir mon message, "Prise en charge UTF-8 native dans SQL Server 2019: Sauveur ou faux prophète?", Pour une analyse détaillée de cette nouvelle fonctionnalité.

Autres conseils

Qu'entendez-vous par «nager dans le flux UCS-2»?

Voici vos options:

Pas recommandé mais possible:

  • Implémentez un UDT. Ce sera beaucoup de travail et vous perdrez la prise en charge du péage (ou la cartographie et certainement certaines fonctionnalités de serveur SQL qui fonctionnent sur les types natifs).
  • Utilisez varbinary (max): vous oblige à faire du code de conversion personnalisé. Aucune indexation de plage.
  • Utilisez nvarchar (n) et allumez la compression des lignes. En commençant par SQL Server 2008 R2, cela utilisera un encodage aussi compact que UTF-8. Mais cela nécessite une édition d'entreprise.

Voir les commentaires à lire sur les inconvénients graves que ces approches ont.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top