Dans quel type de données stocker les données XML: VARCHAR (MAX) ou XML

9

Je suis en train de définir un schéma pour un nouvel ensemble de ressources à l'aide de SQL Server 2008 ... Dans ce cas, chaque enregistrement ( par exemple, une ligne ) devra stocker des fragments XML. De temps en temps; mais pas fréquemment; Je vais devoir interroger le XML pour trouver les valeurs des éléments et des attributs. Si laissé à mes propres moyens, j'aurais tendance à utiliser le type de données xml bien que j'ai été amené à croire que cela était dû à des problèmes. Cela m'amène donc à mes questions.

Compte tenu de ce scénario, quels facteurs dois - je envisager d' en essayant de décider entre le stockage XML dans un xml colonne par rapport à une VARCHAR (MAX) colonne

Si cela peut vous aider… voici quelques détails supplémentaires:

  • Aucune décision n'a été prise concernant l'utilisation de schémas pour ces fragments ( par exemple XSD )
  • La taille des fragments variera de petite à très grande
  • Tout XML sera bien formé
  • Au cours d'une journée, jusqu'à 10 000 fragments seront collectés avec un support de requête en ligne nécessaire pendant environ 3 mois
  • Les requêtes contre le XML se produiront tout au long de la journée mais devraient rester légères avec peu de requêtes simultanées de ce type
JoeGeeky
la source
1
Le type xml ne garantit pas de conserver la forme exacte du xml d'origine, si le document doit être inchangé, alors nvarchar (max) est la seule option.
MartinC
@MartinC Si le fragment est déjà bien formé, quel genre de changement pourrait se produire? Je vous crois, je n'ai tout simplement pas entendu cela avant ... Pouvez-vous m'indiquer plus de détails?
JoeGeeky
Exemple, les balises vides <foo></foo>deviendront<foo />
gbn
@gdn Ahhh, ok ... cela ne change pas le sens, donc ça me va.
JoeGeeky

Réponses:

5

Si des requêtes contre le XML se produisent par les capacités XML du serveur SQL, utilisez le type XML pour stocker un XML afin d'éviter la conversion

Et

gardez à l'esprit que ce type XML peut être stocké un peu plus lentement en raison de la validation xml, mais le type sous-jacent de XML est un fichier varbinary ordinaire (max)

Oleg Dok
la source
1
Les données sous-jacentes ne le sont pas VARBINARY(MAX). Il s'agit d'un format optimisé, ce qui signifie que même si vous n'allez pas l'interroger, vous devez toujours utiliser le XMLtype de données.
Solomon Rutzky
6

quels facteurs dois-je prendre en compte lorsque j'essaie de décider entre le stockage XML dans une xmlcolonne et une varchar(MAX)colonne

Les facteurs sont les suivants:

  1. Le XMLtype est interrogeable / analysable via les expressions XQuery, y compris la possibilité d'utiliser la déclaration FLWOR et l'itération
  2. Les données des XMLvariables et des colonnes peuvent être modifiées en ligne à l'aide d'expressions XQuery via XML DML .
  3. XMLles données sont stockées en UTF-16 LE (Little Endian), ce VARCHAR(MAX)serait donc un mauvais choix car cela pourrait entraîner une perte de données. Par conséquent, la vraie décision devrait être entre XMLet NVARCHAR(MAX), étant donné que NCHAR/ NVARCHARest également UTF-16 LE.
  4. XMLles données peuvent être validées par rapport à un XSD / XML SCHEMA COLLECTION. Aucune validation (en dehors d'assurer une bonne mise en forme) n'est effectuée si aucune collection de schémas XML n'est spécifiée, mais cette option n'est pas disponible lors de l'utilisation NVARCHAR(MAX).
  5. Un avantage majeur du type XML est qu'il est stocké dans un format hautement optimisé (pas VARBINARY(MAX)comme indiqué dans la réponse de @ Oleg) qui ne stocke pas la représentation de chaîne exacte que vous voyez, mais a à la place un dictionnaire de noms d'élément et d'attribut et fait référence pour eux par leur carte d'identité. Il supprime également les espaces blancs. Essayez ce qui suit:

    DECLARE @Test1 XML = N'<Test><TagName>1</TagName><TagName>2</TagName></Test>';
    
    DECLARE @String1 NVARCHAR(MAX) = CONVERT(NVARCHAR(MAX), @Test1);
    
    SELECT DATALENGTH(@Test1) AS [XmlBytes],
           LEN(@String1) AS [StringCharacters],
           DATALENGTH(@String1) AS [StringBytes];
    
    SET @Test1 = N'<Test><TagName>1</TagName><TagName>2</TagName><TagName>3</TagName>
    <TagName>4</TagName><TagName>5</TagName><TagName>6</TagName></Test>';
    
    SET @String1 = CONVERT(NVARCHAR(MAX), @Test1);
    
    SELECT DATALENGTH(@Test1) AS [XmlBytes],
           LEN(@String1) AS [StringCharacters],
           DATALENGTH(@String1) AS [StringBytes];
    

    Retour:

    XmlBytes   StringCharacters   StringBytes
    56         53                 106
    
    XmlBytes   StringCharacters   StringBytes
    84         133                266
    

    Comme vous pouvez le voir dans l'exemple de sortie ci-dessus, l'ajout de quatre éléments (# 3, 4, 5 et 6) a ajouté 80 caractères (donc 80 octets si vous utilisez VARCHAR) et 160 octets à la NVARCHARvariable. Pourtant, il n'a ajouté que 28 octets à la variable XML, ce qui est inférieur à ce qu'il a ajouté VARCHAR(juste au cas où quelqu'un allait plaider en faveur de VARCHARover XMLparce que XMLUTF-16 est [principalement] à deux octets). Cette optimisation peut économiser des tonnes d'espace et est une raison suffisante en soi pour utiliser le XMLtype de données.

Solomon Rutzky
la source