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

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)


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.