Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Speichern von XML-Daten in SQL Server

Bei der Arbeit an der Veröffentlichung von dbForge Transaction Log musste unser Team unter anderem herausfinden, wie typisierte XML-Daten richtig gespeichert werden.

Zunächst ist zu erwähnen, dass SQL Server XML nicht in dem Format speichert, in dem es eingegeben wurde. Ein XML-String wird geparst, in Tags aufgeteilt und somit in einem komprimierten Format gespeichert. Beschreibungselemente, die der Server für unnötig hält, werden verworfen.

Es sollte auch beachtet werden, dass, wenn der Datentyp einer Spalte als einfaches XML angegeben ist, der Server diese Daten als Unicode-Strings speichert.
Beispiel 1.

CREATE TABLE XmlValuesTable ( [uid] [int] IDENTITY PRIMARY KEY, v XML NOT NULL );GOINSERT INTO XmlValuesTable (v)VALUES ('123.456');INSERT INTO XmlValuesTable (v)VALUES ('4.0000000000');

Der Server speichert die Einfügung Daten wie folgt:

F0 04 6E006F0074006500 <- Name "note"EF 000001 <- Namespace 01F8 01 <- tag 01F0 05 66006C006F0061007400 <- Name "float"EF 000002 <- Namespace 02F8 02 <- tag 0211 07 3100320033002E00340035003600 <- string "123.456" F7 <- schließendes TagF0 04 740069006D006500 <- Name "Zeit"EF 000003 <- Namespace 02F8 03 <- Tag 0311 0C 300031003A00320033003A0034003900 <- string <- schließendes <-7 Tag "01:23:45.- schließen" 

Im folgenden Beispiel wird der Spaltendatentyp als durch die XML-Schemasammlung typisiert angegeben.

Beispiel 2.

CREATE XML SCHEMA COLLECTION [XmlValuesSchemaCollection_datetime2] AS'  ';GOCREATE TABLE XmlValuesTable_datetime2 ( [uid] [ int] IDENTITY PRIMARY KEY, v XML(XmlValuesSchemaCollection_datetime2) NOT NULL);GOINSERT INTO XmlValuesTable_datetime2 (v)VALUES (N'2014-06-18T06:39:05.190');GO

In diesem speziellen Fall speichert der Server die Einfügung Daten wie folgt:

 EA 09 014C010015 1A000000 <- Typ Info 0x14C (332) "DateTime2", 0x15 (21) "DateTime" + Offsetf0 09 6400610074006500740069006d0065003200 <- name "datetime2" ef 000001 <- nameSpace 01f8 01f. - geben Sie info7E 02978924A9380B <- "2014-06-18T06:39:05.190"F7 <- schließendes Tag
ein

Auf diese Weise konvertiert der Server die gespeicherten Daten in die im Anhang zu diesem Artikel angegebenen Typen (Sie können die Liste aller Datentypen anzeigen, indem Sie die Abfrage „select * from sys.xml_schema_types“ auf dem Server ausführen).

Schauen wir uns an, wie der Server eine komplexere Struktur speichert, die der in Beispiel 1 ähnelt und mit XML Schema Collection beschrieben wird.

Beispiel 3.

CREATE XML SCHEMA COLLECTION [XmlValuesSchemaCollection] AS'          '; GO CREATE TABLE XmlValuesTable ( [uid] [int] IDENTITY PRIMARY KEY, v XML(XmlValuesSchemaCollection) NOT NULL);GOINSERT INTO XmlValuesTable (v)VALUES ('123.456');

Der Server speichert die Einfügung Daten wie folgt:

EA 05 0001000100 <- Typ infoF0 04 6E006F0074006500 <- Name "note"EF 000001 <- NamespaceF8 01 <- tag 01EA 09 0111000011 12000000 <- Typ info 0x11 (17) "float" + offsetF0 05 01-60706 Float"EF 000002 <- NamespaceF8 02 <- Tag 02EA 05 0011000011 <- Type Info 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- Closing TagEA 09 0116000016 10000000 <- Type Info 0x16 (22) "time " + offsetF0 04 740069006D006500 <- Name "time"EF 000003 <- NamespaceF8 03 <- tag 03EA 05 0016000016 <- type info 0x16 (22) "time"7D 03FDAF4C005B950A <- "01:23:45.789"F7 <- schließender TagF7 <- schließendes Tag

Versuchen wir, der Einfügung einen Schema-Link hinzuzufügen.

Beispiel 4.

INSERT INTO XmlValuesTable (v)VALUES ('123.456');
EA 05 0001000100 <- type infoF0 04 6E006F0074006500 <- Name "note"EF 000001 <- NamespaceF8 01 <- tag 01F0 09 78006D006C006E0073003A00780073006900 <- Name "xmlns:xsi"EF 000200 <- Namespace "xmlns:xsi"F6 02 <- 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 <- tag 03EA 05 0011000011 <- type info 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- schließender TagEA 09 0116000016 10000000 <- type info 0x16 (22) " time" + offsetF0 04 740069006D006500 <- Name "time"EF 000004 <- NamespaceF8 04 <- tag 08EA 05 0016000016 <- type info 0x16 (22) "time"7D 03FDAF4C005B950A <- "01:23:45.789"F7 <- closeing tagF7 <- schließendes Tag

Wie Sie sehen, hat der Server den Namensraum sorgfältig als Attribut gespeichert und fast die Hälfte des Platzes dafür verwendet, obwohl der Namensraum hier keinen wirklich sinnvollen Zweck erfüllt – die Daten wurden so gespeichert, wie sie es wären ohne Namensraum gespeichert.

Schlussfolgerung

Aus dem Obigen kann es scheinen, dass Sie die Größe einer Datenbank reduzieren können, indem Sie einige Datentypen (z. B. Float) als typisierte Werte speichern, da 4 Bytes erheblich weniger Speicherplatz benötigen als derselbe Wert, der als Unicode-Zeichenfolge gespeichert wird. Sie sollten jedoch bedenken, dass für jeden Wert zusätzliche 7-18 Bytes verwendet werden, um seinen Typ zu beschreiben und ihn an die erforderliche Position zu verschieben.

Nachtrag

Korrelation von XML-Typen, Basistypen und Datentypen, die der Server verwendet, um typisierte Werte zu speichern.

XML-Typ Basistyp Gespeichert als Typ Größe in Bytes
jeder Typ Zeichenfolge 2 * Zeichen
jederEinfacheTyp jeder Typ Zeichenfolge
Zeichenfolge beliebiger Einfacher Typ Zeichenfolge
boolesch beliebiger Einfacher Typ boolesch 1
schwimmen beliebiger Einfacher Typ schwimmen 4
doppelt beliebiger Einfacher Typ doppelt 8
dezimal beliebiger Einfacher Typ SqlDecimal 20
Dauer beliebiger Einfacher Typ Zeichenfolge
dateTime beliebiger Einfacher Typ *1
Zeit beliebiger Einfacher Typ *1
Datum beliebiger Einfacher Typ *1
gJahrMonat beliebiger Einfacher Typ Zeichenfolge
gJahr beliebiger Einfacher Typ Zeichenfolge
gMonatTag beliebiger Einfacher Typ Zeichenfolge
Tag beliebiger Einfacher Typ Zeichenfolge
gMonat beliebiger Einfacher Typ Zeichenfolge
hexBinary beliebiger Einfacher Typ Array von Bytes
base64Binary beliebiger Einfacher Typ Array von Bytes
jeder URI beliebiger Einfacher Typ Zeichenfolge
QName beliebiger Einfacher Typ Zeichenfolge
normalisierterString Zeichenfolge Zeichenfolge
Token Zeichenfolge Zeichenfolge
Sprache Zeichenfolge Zeichenfolge
Name Zeichenfolge Zeichenfolge
NCName Zeichenfolge Zeichenfolge
ENTITÄT Zeichenfolge Zeichenfolge
NMTOKEN Zeichenfolge Zeichenfolge
Ganzzahl dezimal SqlDecimal 20
nonPositiveInteger Ganzzahl SqlDecimal 20
negativeGanzzahl nonPositiveInteger SqlDecimal 20
lang Ganzzahl SqlDecimal 20
int lang SqlDecimal 20
kurz int SqlDecimal 20
Byte kurz SqlDecimal 20
nonNegativeInteger Ganzzahl SqlDecimal 20
unsignedLong nonNegativeInteger SqlDecimal 20
unsignedInt unsignedLong SqlDecimal 20
unsignedShort unsignedInt SqlDecimal 20
unsignedByte unsignedShort SqlDecimal 20
positiveInteger nonNegativeInteger SqlDecimal 20
char Zeichenfolge Zeichenfolge
nchar Zeichenfolge Zeichenfolge
varchar Zeichenfolge Zeichenfolge
nvarchar Zeichenfolge Zeichenfolge
Text Zeichenfolge Zeichenfolge
ntext Zeichenfolge Zeichenfolge
varbinary base64Binary Array von Bytes
binär base64Binary Array von Bytes
Bild base64Binary Array von Bytes
Zeitstempel base64Binary Array von Bytes
timestampNumeric lang SqlDecimal 20
numerisch dezimal SqlDecimal 20
bigint lang SqlDecimal 20
smallint kurz SqlDecimal 20
tinyint unsignedByte SqlDecimal 20
bisschen boolesch boolesch 1
echt schwimmen schwimmen 4
datetime dateTime *1
smalldatetime dateTime *1
Geld dezimal SqlDecimal
Kleingeld dezimal SqlDecimal
eindeutige Kennung dezimal Zeichenfolge
datetime2 dateTime *1
datetimeoffset dateTime *1
Hierarchie-ID Zeichenfolge Zeichenfolge
dbobject jeder URI Zeichenfolge

*1 – Datums-/Zeitinformationen. Der konkrete Typ wird durch den Wert definiert.

Wert Gespeichert als Typ Größe in Byte
DatumOffset Datum (Anzahl Tage) 3
DateOffset (2019-09-16+02:00) DateTimeOffset 11
DatumUhrzeit DatumUhrzeit 7-9 hängt von der Genauigkeit ab
DateTimeOffset DateTimeOffset 9
Zeit DatumUhrzeit 7-9 hängt von der Genauigkeit ab
Zeitversatz (01:23:45Z) DateTimeOffset 9