Avec SQL Server 2019 Microsoft de soutien UTF-8 pour CHAR
et VARCHAR
les types de données et dit:
Cette fonctionnalité peut permettre des économies de stockage importantes, selon le jeu de caractères utilisé. Par exemple, la modification d'un type de données de colonne existant avec des chaînes ASCII de NCHAR (10) à CHAR (10) à l'aide d'un classement activé UTF-8, se traduit par une réduction de près de 50% des exigences de stockage. Cette réduction est due au fait que NCHAR (10) nécessite 22 octets pour le stockage, tandis que CHAR (10) nécessite 12 octets pour la même chaîne Unicode.
UTF-8 semble soutenir chaque script, donc en gros , nous pouvons commencer à stocker des données Unicode dans varchar
et char
colonnes. Et comme indiqué dans la documentation, cela peut réduire la taille des tables et des index, et à partir de là, nous pouvons obtenir des performances encore meilleures, car une plus petite quantité de données est lue.
Je me demande si cela signifie que nous pouvons arrêter d'utiliser nvarchar
et des nchar
colonnes qui implémentent UTF-16?
Quelqu'un peut-il pointer un scénario et une raison, pour ne pas utiliser les types de données char avec l' UTF
encodage et continuer à utiliser ceux n-chars?
CHAR
types UTF-8 que des types Unicode (avec ou sans compression, car les données doivent finalement être décompressées pour être traitées). Considérez également que le type de chaîne natif de Windows est Unicode, donc les chaînes UTF-8 doivent souvent être décodées. Les compromis impliqués signifient qu'il est peu probable que lesN
types soient retirés de si tôt.CHAR
est probablement SQL Server sous Linux, si le moteur obtient un support natif pour le traitement des chaînes directement en UTF-8 - ici UTF-8 est le jeu de caractères «natif» (plus ou moins) et garder les chaînes autour comme UTF-16 est l'alternative moins efficace.CHAR
Bien sûr, cela ne fera pas de mal de l'utiliser sur Windows dans des endroits où vous l'utilisez déjà , car les classements restreignant les caractères pouvant être stockés n'ont jamais été attrayants.Réponses:
Réduction de la taille est seulement possible si la plupart des personnages sont essentiellement
[space]
,0 - 9
,A - Z
,a - z
et certains signes de ponctuation de base. En dehors de cet ensemble spécifique de caractères (en termes d'utilisation pratique, valeurs ASCII standard 32 - 126), vous serez au mieux égal en taille àNVARCHAR
/ UTF-16, ou dans de nombreux cas plus grand.Faites attention. L'UTF-8 n'est pas un commutateur magique «tout réparer». Toutes choses étant égales par ailleurs, oui, lire moins améliore les performances. Mais ici "toutes les autres choses" ne sont pas égales. Même lorsque vous ne stockez que des caractères ASCII standard (ce qui signifie que tous les caractères font 1 octet, ce qui nécessite donc la moitié de l'espace par rapport au stockage
NVARCHAR
), il existe une légère pénalité de performance pour l'utilisation de l'UTF-8. Je crois que le problème est dû au fait que l'UTF-8 est un codage de longueur variable, ce qui signifie que chaque octet doit être interprété tel qu'il est lu afin de savoir s'il s'agit d'un caractère complet ou si l'octet suivant en fait partie. Cela signifie que toutes les opérations de chaîne doivent commencer au début et se poursuivre octet par octet. D'autre part,NVARCHAR
/ UTF-16 est toujours de 2 octets (même les caractères supplémentaires sont composés de deux points de code de 2 octets), de sorte que tout peut être lu par blocs de 2 octets.Lors de mes tests, même avec uniquement des caractères ASCII standard, le stockage des données au format UTF-8 n'a pas permis de gagner du temps, mais était nettement pire pour le temps CPU. Et c'était sans compression de données, donc au moins il y avait moins d'espace disque utilisé. Mais, lors de l'utilisation de la compression, l'espace requis pour UTF-8 n'était que de 1% à 1,5% plus petit. Donc, effectivement, aucune économie d'espace, mais un temps processeur plus long pour UTF-8.
Les choses deviennent plus compliquées lors de l'utilisation
NVARCHAR(MAX)
car la compression Unicode ne fonctionne pas avec ce type de données, même si la valeur est suffisamment petite pour être stockée en ligne. Mais, si les données sont suffisamment petites, elles devraient toujours bénéficier de la compression de lignes ou de pages (auquel cas elles deviennent en fait plus rapides que UTF-8). Cependant, les données hors ligne ne peuvent utiliser aucune compression. Pourtant, faire de la table un index de colonnes en cluster réduit considérablement la taille deNVARCHAR(MAX)
(même si elle est toujours légèrement plus grande que UTF-8 lors de l'utilisation de l'index de colonnes en cluster).Absolument. En fait, je ne trouve pas vraiment de raison impérieuse de l'utiliser dans la plupart des cas. Le seul scénario qui bénéficie vraiment de l'UTF-8 est:
VARCHAR
)Mes tests montrent que dans presque tous les cas, NVARCHAR était plus rapide, surtout quand il y avait plus de données. En fait, 21 000 lignes avec une moyenne de 5 000 caractères par ligne nécessitaient 165 Mo pour UTF-8 et 236 Mo pour
NVARCHAR
non compressé. Et pourtant, ilNVARCHAR
était 2x plus rapide en temps écoulé, et au moins 2x plus rapide (parfois plus) en temps CPU. Pourtant, il occupait 71 Mo de plus sur le disque.En dehors de cela, je ne recommanderais toujours pas d'utiliser UTF-8, au moins à partir de CTP 2, en raison d'une variété de bogues que j'ai trouvés dans cette fonctionnalité.
Pour une analyse détaillée de cette nouvelle fonctionnalité, y compris une explication des différences entre UTF-16 et UTF-8, et une liste de ces bogues, veuillez consulter mon article:
Prise en charge native UTF-8 dans SQL Server 2019: Sauveur ou faux prophète?
la source
La prise en charge UTF-8 vous offre un nouvel ensemble d'options. Les économies d'espace potentielles (sans compression de lignes ou de pages ) sont une considération, mais le choix du type et du codage devrait probablement être principalement basé sur les exigences réelles de comparaison, de tri, d' importation et d'exportation de données .
Vous devrez peut-être modifier plus que vous ne le pensez, car par exemple, un
nchar(1)
type fournit deux octets de stockage. Cela suffit pour stocker n'importe quel caractère dans BMP (points de code 000000 à 00FFFF). Certains des caractères de cette plage seraient codés avec seulement 1 octet en UTF-8 tandis que d'autres nécessiteraient 2 ou même 3 octets (voir ce tableau de comparaison pour plus de détails). Par conséquent, assurer la couverture du même ensemble de caractères en UTF-8 nécessiteraitchar(3)
.Par exemple:
donne l'erreur familière:
Ou si l'indicateur de trace 460 est actif:
Étendre la colonne UTF8
char(2)
ouvarchar(2)
résoudre l'erreur pourNCHAR(911)
:Cependant, si c'était par exemple
NCHAR(8364)
, vous auriez besoin de développer la colonne plus loin, àchar(3)
ouvarchar(3)
.Notez également que les classements UTF-8 utilisent tous des caractères supplémentaires, donc ne fonctionneront pas avec la réplication.
Mis à part toute autre chose, le support UTF-8 n'est que dans l'aperçu pour le moment, donc pas disponible pour une utilisation en production.
la source