Em que tipo de dados armazenar dados XML: VARCHAR (MAX) ou XML

9

Estou definindo um esquema para um novo conjunto de recursos usando o SQL Server 2008 ... Nesse caso, cada registro ( por exemplo, linha ) precisará armazenar fragmentos XML. De tempos em tempos; embora não frequentemente; Vou precisar consultar o XML para encontrar valores de elemento e atributo. Se deixado por conta própria, eu tenderia a usar o tipo de dados xml, embora tenha sido levado a acreditar que isso é causado por problemas. Então isso me leva às minhas perguntas.

Diante desse cenário, o que fatores devo considerar quando se tenta decidir entre o armazenamento de XML em um xml coluna vs. um varchar (MAX) coluna

Se ajudar ... aqui estão alguns detalhes adicionais:

  • Nenhuma decisão foi tomada com relação ao uso de esquemas para esses fragmentos ( por exemplo, XSDs )
  • Os tamanhos dos fragmentos variam de pequeno a muito grande
  • Todo o XML será bem formado
  • Ao longo de um dia, haverá até 10.000 fragmentos coletados com o suporte a consultas on-line necessário por aproximadamente 3 meses
  • As consultas contra o XML ocorrerão ao longo do dia, mas devem permanecer leves com poucas consultas simultâneas desse tipo
JoeGeeky
fonte
11
O tipo xml não garante preservar a forma exata do xml original, se houver um requisito para que o documento permaneça inalterado, então nvarchar (max) é a única opção.
Martinc
@ MartinC Se o fragmento já estiver bem formado, que tipo de mudança poderia ocorrer? Acredito em você, só não ouvi isso antes ... Você pode me indicar mais alguns detalhes?
JoeGeeky
Exemplo, as tags vazias <foo></foo>se tornarão<foo />
gbn
@ gdn Ahhh, ok ... isso não muda o significado, então está tudo bem comigo.
JoeGeeky

Respostas:

5

Se as consultas contra o XML ocorrerem pelos recursos xml do servidor sql, use o tipo XML para armazenar um xml para evitar a transmissão

E

lembre-se de que o tipo XML pode ser armazenado um pouco mais devagar devido à validação de xml, mas o tipo subjacente de XML é varbinário comum (máximo)

Oleg Dok
fonte
11
Os dados subjacentes não são VARBINARY(MAX). É um formato otimizado, o que significa que, mesmo que você não queira consultá-lo, você ainda deve usar o XMLtipo de dados.
Solomon Rutzky 29/03
6

que fatores devo considerar ao tentar decidir entre armazenar XML em uma xmlcoluna e uma varchar(MAX)coluna

Os fatores são:

  1. O XMLtipo é consultável / analisável através de expressões XQuery, incluindo a possibilidade de usar a instrução e a iteração FLWOR
  2. Os dados em XMLvariáveis ​​e colunas podem ser modificados em linha usando expressões XQuery via XML DML .
  3. XMLOs dados são armazenados como UTF-16 LE (Little Endian), portanto, VARCHAR(MAX)seria uma má escolha, pois poderia resultar em perda de dados. Portanto, a verdadeira decisão deve estar entre XMLe NVARCHAR(MAX), considerando que NCHAR/ NVARCHARtambém é UTF-16 LE.
  4. XMLos dados podem ser validados com relação a um XSD / XML SCHEMA COLLECTION. Nenhuma validação (fora de garantir a boa formação) é feita se nenhuma XML Schema Collection for especificada, mas essa opção não estará disponível ao usar NVARCHAR(MAX).
  5. Um grande benefício do tipo XML é que ele é armazenado em um formato altamente otimizado (não VARBINARY(MAX)como indicado na resposta de @ Oleg) que não armazena a representação exata da string que você vê, mas possui um dicionário de nomes de elemento e atributo e se refere para eles por sua identificação. Ele também remove os espaços em branco. Tente o seguinte:

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

    Devoluções:

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

    Como você pode ver no exemplo de saída acima, adicionar quatro elementos (nºs 3, 4, 5 e 6) adicionou 80 caracteres (portanto, 80 bytes se estiver usando VARCHAR) e 160 bytes à NVARCHARvariável. No entanto, ele adicionou apenas 28 bytes à variável XML, que é menor do que a adicionada VARCHAR(apenas no caso de alguém argumentar a favor do VARCHARexcesso, XMLporque XMLé o UTF-16, que é [principalmente] de byte duplo). Essa otimização pode economizar muito espaço e é motivo suficiente para usar o XMLtipo de dados.

Solomon Rutzky
fonte