Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

UCS-2 et SQL Server

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

Leur décision de choisir UCS-2 est assez logique étant donné que UTF-16 a été introduit au milieu de 1996 et entièrement spécifié en 2000. De nombreux autres systèmes l'utilisent (ou l'ont utilisé) également (veuillez consulter :https://en.wikipedia.org/wiki/UTF-16#Usage ). Leur décision de continuer avec cela pourrait ê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 d'UCS-2 pour prendre en charge UTF-16 doit être purement fonctionnelle sans qu'il soit nécessaire de modifier les données existantes.

Um non. La création d'un type personnalisé défini par l'utilisateur via SQLCLR n'est pas , de quelque manière que ce soit, vous procurera un remplacement de n'importe quel type natif. C'est très pratique pour créer quelque chose pour gérer des données spécialisées. Mais les chaînes, même d'un encodage différent, sont loin d'être spécialisées. Suivre cette voie pour vos données de chaîne détruirait toute facilité d'utilisation de votre système, sans parler des performances, car vous ne seriez pas en mesure d'utiliser aucune 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 en performances globales. Le stockage d'un UDT se fait en le sérialisant dans un VARBINARY . Donc, pour faire n'importe quoi comparaison de chaînes OU tri, en dehors d'une comparaison "binaire" / "ordinale", vous devrez convertir toutes les autres valeurs, une par une, en UTF-8 pour ensuite effectuer la comparaison de chaînes qui peut tenir compte des différences linguistiques.

De plus, cette "documentation" n'est vraiment qu'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 la fonctionnalité, mais rien concernant les performances.

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

Corriger. UTF-16 et UCS-2 utilisent tous deux des points de code à 2 octets. Mais UTF-16 utilise certains d'entre eux par paires (c'est-à-dire des paires de substitution) pour mapper des caractères supplémentaires. Les points de code utilisés pour ces paires sont réservés à cette fin dans UCS-2 et ne sont donc pas utilisés pour mapper vers 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.

Correct, quoique trompeur. Oui, UTF-8 est à largeur variable, mais UTF-16 est également légèrement variable puisque tous les caractères supplémentaires sont composés de deux points de code à deux octets. 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 encodage Unicode n'est pas capable d'encoder tous les autres points de code. Alors que UCS-2 peut les contenir mais pas les interpréter, UTF-16 et UTF-32 peuvent tous deux mapper tous les points de code Unicode, tout comme UTF-8.

C'est peut-être vrai, mais ce n'est absolument pas pertinent d'un point de vue opérationnel.

Encore une fois, vrai, mais totalement hors de propos puisque UTF-16 et UTF-32 mappent également tous les points de code Unicode.

Selon les circonstances, cela pourrait très bien être vrai, et vous avez raison de vous inquiéter d'un tel gaspillage. Cependant, comme je l'ai mentionné dans la question qui a mené à celle-ci ( Prise en charge UTF-8, SQL Server 2012 et l'UDT UTF8String ), vous avez quelques options pour atténuer la quantité d'espace perdu si la plupart des lignes peuvent tenir dans VARCHAR pourtant certains doivent être NVARCHAR . La meilleure option consiste à activer la COMPRESSION DE LIGNE ou la COMPRESSION DE PAGE (Enterprise Editon uniquement !). À partir de SQL Server 2008 R2, ils autorisent NVARCHAR non-MAX 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 même meilleur que UTF-8. NVARCHAR(MAX) les champs ne peuvent pas utiliser cette compression sophistiquée , mais leurs données IN ROW peuvent bénéficier d'une compression ROW et/ou PAGE régulière. Veuillez consulter ce qui suit pour une description de cette compression et un tableau comparant les tailles de données pour :UCS-2 brut / UTF-16, UTF-8 et UCS-2 / UTF-16 avec la compression de données activée.

SQL Server 2008 R2 - Compression UCS2 qu'est-ce que c'est - Impact sur les systèmes SAP

Veuillez également consulter la page MSDN pour Compression des données pour plus de détails car il existe certaines restrictions (en plus d'être disponible uniquement dans Enterprise Edition -- MAIS mis à la disposition de tous éditions commençant par SQL Server 2016, SP1 !!) et certaines circonstances où la compression peut aggraver les choses.

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

Aucun auquel je puisse penser. Eh bien, tant que vous ne suivez aucun conseil horrible pour faire quelque chose comme implémenter cet UDT, ou convertir toutes les chaînes en VARBINARY , ou en utilisant NVARCHAR(MAX) pour tous les champs de chaîne ;-). Mais de toutes les choses dont vous pourriez 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'absence de prise en charge native de l'UTF-8 est extrêmement important, vous devrez peut-être trouver un autre SGBDR à utiliser qui autorise l'UTF-8.

MISE À JOUR 2018-10-02

Bien que ce ne soit pas encore une option viable, SQL Server 2019 introduit la prise en charge native de l'UTF-8 dans VARCHAR / CHAR Types de données. Il y a actuellement trop de bogues pour qu'il puisse être utilisé, mais s'ils sont corrigés, alors c'est une option pour certains scénarios. Veuillez consulter mon message, "Prise en charge native de l'UTF-8 dans SQL Server 2019 :sauveur ou faux prophète ? ", pour une analyse détaillée de cette nouvelle fonctionnalité.