sql >> Base de Datos >  >> RDS >> Sqlserver

Almacenamiento de datos XML en SQL Server

Cuando trabajaba en el lanzamiento de dbForge Transaction Log, entre otras tareas, nuestro equipo tuvo que descifrar cómo almacenar correctamente los datos XML escritos.

Para empezar, vale la pena mencionar que SQL Server no almacena XML en el formato en que se ingresó. Una cadena XML se analiza, se divide en etiquetas y, por lo tanto, se almacena en un formato comprimido. Los elementos de descripción que el servidor considera innecesarios se descartan.

También debe tenerse en cuenta que, si el tipo de datos de una columna se especifica como XML simple, el servidor almacenará estos datos como cadenas Unicode.
Ejemplo 1.

CREAR TABLA XmlValuesTable ([uid] [int] CLAVE PRINCIPAL DE IDENTIDAD, v XML NO NULO); INSERTAR EN XmlValuesTable (v)VALUES ('123.456');INSERTAR EN XmlValuesTable (v)VALUES ('4.0000000000');

El servidor almacenará el insertar datos de la siguiente manera:

 F0 04 6E006F0074006500 <- Nombre "Nota" EF 000001 <- Espacio de nombres 01F8 01 <- TAG 01F0 05 66006C006F0061007400 <- Nombre "Float" EF 000002 <- Namespace 02F8 02 <- Tag 0211 07 31003200333002E F7 <- etiqueta de cierreF0 04 740069006D006500 <- Nombre "tiempo"EF 000003 <- Espacio de nombres 02F8 03 <- etiqueta 0311 0C 300031003A00320033003A00340035002E00370038003900 <- cadena "01 <- etiqueta de cierre"F7 <- etiqueta de cierre 
 En el siguiente ejemplo, el tipo de datos de la columna se especifica como escrito a través de la colección de esquemas XML.

Ejemplo 2.

CREAR UNA COLECCIÓN DE ESQUEMAS XML [XmlValuesSchemaCollection_datetime2] AS'  ';GOCREATE TABLE XmlValuesTable_datetime2 ( [uid] [ int] CLAVE PRINCIPAL DE IDENTIDAD, v XML(XmlValuesSchemaCollection_datetime2) NOT NULL);GOINSERT INTO XmlValuesTable_datetime2 (v)VALUES (N'2014-06-18T06:39:05.190');GO

En este caso particular, el servidor almacenará el insertar datos de la siguiente manera:

 EA 09 014C010015 1A000000 <- Tipo de información 0x14c (332) "Datetime2", 0x15 (21) "Datetime" + Offsetf0 09 6400610074006500740069006D0065003200 <- Nombre "DateTime2" EF 000001 <- Names NameSpace - escriba info7E 02978924A9380B <- "2014-06-18T06:39:05.190"F7 <- etiqueta de cierre

De esta forma, el servidor convierte los datos almacenados a los tipos especificados en el apéndice de este artículo (puede ver la lista de todos los tipos de datos ejecutando la consulta "select * from sys.xml_schema_types" en el servidor).

Echemos un vistazo a cómo el servidor guardará una estructura más compleja similar a la del ejemplo 1 y descrita con XML Schema Collection.

Ejemplo 3.

CREAR UNA COLECCIÓN DE ESQUEMAS XML [XmlValuesSchemaCollection] AS'          '; IR A CREAR TABLA XmlValuesTable ([uid] [int] CLAVE PRINCIPAL DE IDENTIDAD, v XML(XmlValuesSchemaCollection) NOT NULL);GOINSERTAR EN XmlValuesTable (v)VALUES ('123.456');

El servidor guardará el insertar datos de la siguiente manera:

EA 05 0001000100 <- tipo infoF0 04 6E006F0074006500 <- Nombre "nota" EF 000001 <- NamespaceF8 01 <- etiqueta 01EA 09 0111000011 12000000 <- tipo info 0x11 (17) "float" +F0 060060006 offsetF0 06 060004 " float"EF 000002 <- NamespaceF8 02 <- etiqueta 02EA 05 0011000011 <- tipo info 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- cierre tagEA 09 0116000016 10000000 <- tipo info 0x16 (22) "tiempo " + offsetF0 04 740069006D006500 <- Nombre "hora"EF 000003 <- Espacio de nombresF8 03 <- etiqueta 03EA 05 0016000016 <- tipo de información 0x16 (22) "hora"7D 03FDAF4C005B950A <- "01:23:45.789"F7 <- etiqueta de cierreF7 <- etiqueta de cierre

Intentemos agregar un enlace de esquema al inserto.

Ejemplo 4.

INSERTAR EN XmlValuesTable (v)VALUES ('123.456');
 EA 05 0001000100 <- Tipo InfoF0 04 6E006F0074006500 <- Nombre "Nota" EF 000001 <- NamespaceF8 01 <- TAG 01F0 09 78006D006C006E0073003A00780073006900 <- Nombre "XMLNS:XSI" EF 000 "000I. <- Attribute11 29 68007400740070003A002F002F007700770077002E00770033002E006F00720067002F0032003000300031002F0058004D004C0053006300680065006D0061002D0069006E007300740061006E0063006500 <- "http://www.w3.org/2001/XMLSchema-instance"F5 <- closing bracketEA 09 0111000011 12000000 <- type info 0x11 (17) "float" + offsetF0 05 66006C006F0061007400 <- Name "float"EF 000003 <- NamespaceF8 03 <- etiqueta 03EA 05 0011000011 <- tipo info 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- cierre tagEA 09 0116000016 10000000 <- tipo info 0x16 (22) " tiempo" + offsetF0 04 740069006D006500 <- Nombre "tiempo"EF 000004 <- NamespaceF8 04 <- etiqueta 08EA 05 0016000016 <- tipo info 0x16 (22) "tiempo"7D 03FDAF4C005B950A <- "01:23:45.789"F7 <- cierre tagF7 <- etiqueta de cierre

Como puede ver, el servidor guardó cuidadosamente el espacio de nombres como un atributo y usó casi la mitad del espacio para esto, incluso a pesar de que el espacio de nombres realmente no tiene ningún propósito útil aquí:los datos se guardaron de la misma manera. guardado sin el espacio de nombres.

Conclusión

De lo anterior, puede parecer que puede reducir el tamaño de una base de datos almacenando algunos tipos de datos (por ejemplo, flotantes) como valores escritos, ya que 4 bytes requieren mucho menos almacenamiento que el mismo valor guardado como una cadena Unicode. Sin embargo, debe tener en cuenta que se utilizan de 7 a 18 bytes adicionales para cada valor para describir su tipo y moverlo a la posición necesaria.

Anexo

Correlación de tipos XML, tipos base y tipos de datos que utiliza el servidor para almacenar valores escritos.

Tipo XML Tipo básico Almacenado como tipo Tamaño en bytes
cualquier tipo cadena 2 * caracteres
cualquierTipoSimple cualquier tipo cadena
cadena cualquierTipoSimple cadena
booleano cualquierTipoSimple booleano 1
flotar cualquierTipoSimple flotar 4
doble cualquierTipoSimple doble 8
decimales cualquierTipoSimple SqlDecimal 20
duración cualquierTipoSimple cadena
fechaHora cualquierTipoSimple *1
tiempo cualquierTipoSimple *1
fecha cualquierTipoSimple *1
gAñoMes cualquierTipoSimple cadena
gAño cualquierTipoSimple cadena
gMesDía cualquierTipoSimple cadena
gDía cualquierTipoSimple cadena
gMes cualquierTipoSimple cadena
hexBinario cualquierTipoSimple matriz de bytes
base64Binario cualquierTipoSimple matriz de bytes
cualquierURI cualquierTipoSimple cadena
Nombre Q cualquierTipoSimple cadena
cadena normalizada cadena cadena
ficha cadena cadena
idioma cadena cadena
Nombre cadena cadena
NombreNC cadena cadena
ENTIDAD cadena cadena
NMTOKEN cadena cadena
entero decimales SqlDecimal 20
entero no positivo entero SqlDecimal 20
entero negativo entero no positivo SqlDecimal 20
largo entero SqlDecimal 20
int largo SqlDecimal 20
corto int SqlDecimal 20
byte corto SqlDecimal 20
entero no negativo entero SqlDecimal 20
unsignedLargo entero no negativo SqlDecimal 20
unsignedInt unsignedLargo SqlDecimal 20
corto sin firmar unsignedInt SqlDecimal 20
Byte sin firmar corto sin firmar SqlDecimal 20
Entero positivo entero no negativo SqlDecimal 20
caracter cadena cadena
nchar cadena cadena
varchar cadena cadena
nvarchar cadena cadena
texto cadena cadena
ntext cadena cadena
varbinario base64Binario matriz de bytes
binario base64Binario matriz de bytes
imagen base64Binario matriz de bytes
marca de tiempo base64Binario matriz de bytes
timestampNumeric largo SqlDecimal 20
numérico decimales SqlDecimal 20
grande largo SqlDecimal 20
minúscula corto SqlDecimal 20
tinyint Byte sin firmar SqlDecimal 20
bit booleano booleano 1
real flotar flotar 4
fechahora fechaHora *1
pequeña fecha y hora fechaHora *1
dinero decimales SqlDecimal
dinero pequeño decimales SqlDecimal
identificador único decimales cadena
fechahora2 fechaHora *1
desplazamiento de fecha y hora fechaHora *1
id de jerarquía cadena cadena
objetobd cualquierURI cadena

*1 – información de fecha/hora. El tipo específico se define por el valor.

Valor Almacenado como tipo Tamaño en bytes
Compensación de fecha Fecha (cantidad de días) 3
Compensación de fecha (2019-09-16+02:00) DateTimeOffset 11
FechaHora FechaHora 7-9 depende de la precisión
DateTimeOffset DateTimeOffset 9
Tiempo FechaHora 7-9 depende de la precisión
Compensación de tiempo (01:23:45Z) DateTimeOffset 9