En qué tipo de datos almacenar datos XML: VARCHAR (MAX) o XML

9

Estoy definiendo un esquema para un nuevo conjunto de recursos usando SQL Server 2008 ... En este caso, cada registro ( por ejemplo, fila ) necesitará almacenar fragmentos XML. De vez en cuando; aunque no con frecuencia; Necesitaré consultar el XML para encontrar valores de elementos y atributos. Si lo dejara en mis propios dispositivos, tendería a usar el tipo de datos xml , aunque me han hecho creer que esto está forjado con problemas. Eso me lleva a mis preguntas.

Ante este escenario, ¿qué factores debería estar pensando cuando se trata de decidir entre el almacenamiento XML en un xml columna frente a un varchar (max) columna

Si ayuda ... aquí hay algunos detalles adicionales:

  • No se ha tomado ninguna decisión con respecto al uso de esquemas para estos fragmentos ( por ejemplo, XSD )
  • El tamaño de los fragmentos variará de pequeño a muy grande.
  • Todos los XML estarán bien formados
  • En el transcurso de un día, se recolectarán hasta ~ 10,000 fragmentos con soporte de consulta en línea necesario durante ~ 3 meses
  • Las consultas contra el XML se realizarán a lo largo del día, pero deben permanecer ligeras con pocas consultas concurrentes de este tipo
JoeGeeky
fuente
1
El tipo xml no garantiza preservar la forma exacta del xml original, si hay un requisito para que el documento no cambie, entonces nvarchar (max) es la única opción.
MartinC
@MartinC Si el fragmento ya está bien formado, ¿qué tipo de cambio podría ocurrir? Te creo, simplemente no he escuchado esto antes ... ¿Puedes señalarme algunos detalles más?
JoeGeeky
Ejemplo, las etiquetas vacías <foo></foo>se convertirán<foo />
gbn
@gdn Ahhh, ok ... esto no cambia el significado, así que eso está bien para mí.
JoeGeeky

Respuestas:

5

Si las consultas contra el XML se realizarán mediante las capacidades xml del servidor sql, utilice el tipo XML para almacenar un xml para evitar la conversión

Y

tenga en cuenta que ese tipo de XML puede almacenarse un poco más lento debido a la validación xml, pero el tipo subyacente de XML es varbinary ordinario (max)

Oleg Dok
fuente
1
Los datos subyacentes no lo son VARBINARY(MAX). Es un formato optimizado, lo que significa que incluso si no va a consultarlo, aún debe usar el XMLtipo de datos.
Solomon Rutzky
6

¿Qué factores debo tener en cuenta al tratar de decidir entre almacenar XML en una xmlcolumna frente a una varchar(MAX)columna?

Los factores son:

  1. El XMLtipo es consultable / analizable a través de expresiones XQuery, incluido el uso de la instrucción FLWOR y la iteración
  2. Los datos en XMLvariables y columnas se pueden modificar en línea utilizando expresiones XQuery a través de XML DML .
  3. XMLlos datos se almacenan como UTF-16 LE (Little Endian), por VARCHAR(MAX)lo que sería una mala elección ya que podría provocar la pérdida de datos. Por lo tanto, la verdadera decisión debe ser entre XMLy NVARCHAR(MAX), dado que NCHAR/ NVARCHARes también UTF-16 LE.
  4. XMLlos datos se pueden validar contra un XSD / XML SCHEMA COLLECTION. No se realiza ninguna validación (aparte de garantizar una buena formabilidad) si no se especifica una Colección de esquemas XML, pero esta opción no está disponible cuando se usa NVARCHAR(MAX).
  5. Una de las principales ventajas del tipo XML es que se almacena en un formato altamente optimizado (no VARBINARY(MAX)como se indica en la respuesta de @ Oleg) que no almacena la representación de cadena exacta que ve, sino que tiene un diccionario de nombres de Elementos y Atributos y referencias a ellos por su identificación. También elimina los espacios en blanco. Intenta lo siguiente:

    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];

    Devoluciones:

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

    Como puede ver en el ejemplo de salida anterior, al agregar cuatro elementos (#s 3, 4, 5 y 6) se agregaron 80 caracteres (de ahí 80 bytes si se usa VARCHAR) y 160 bytes a la NVARCHARvariable. Sin embargo, sólo se añade 28 bytes para la variable XML, que es menos de lo que añadido para VARCHAR(sólo en caso de que alguien iba a argumentar a favor de VARCHARmás XML, porque XMLes UTF-16, que es [la mayoría] de doble byte). Esta optimización puede ahorrar toneladas de espacio, y es motivo suficiente por sí solo para usar el XMLtipo de datos.

Solomon Rutzky
fuente