sql >> Database teknologi >  >> RDS >> Sqlserver

Lagring af XML-data i SQL Server

Da vi arbejdede på udgivelsen af ​​dbForge Transaction Log, blandt andre opgaver, måtte vores team puslespille ud, hvordan man korrekt gemmer indtastede XML-data.

Til at starte med er det værd at nævne, at SQL Server ikke gemmer XML i det format, det blev indtastet. En XML-streng parses, opdeles til tags og gemmes således i et komprimeret format. Beskrivelseselementer, som serveren anser for unødvendige, kasseres.

Det skal også huskes, at hvis datatypen for en kolonne er angivet som simpel XML, vil serveren gemme disse data som Unicode-strenge.
Eksempel 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');

Serveren gemmer indsættelsen data som følger:

 F0 04 6E006F0074006500 <- navn "note" EF 000001 <- navneområde 01f8 01 <- Tag 01f0 05 66006C006F0061007400 <- Navn "Float" EF 000002 <-Namespace 02f8 02 <- Tag 0211 07 31120030030030000 F7 <- Lukning af TAGF0 04 740069006D006500 <- Navn "Time" EF 000003 <- Navneområde 02f8 03 <- Tag 0311 0c 300031003A00320033003A00340035002E00370038003900 <- String "01:23:45.789" F7 <- Lukning Mærk 

I det følgende eksempel er kolonnedatatypen angivet som indtastet gennem XML Schema Collection.

Eksempel 2.

OPRET XML-SKEMA-INDSAMLING [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'); 

I dette særlige tilfælde vil serveren gemme indsættelsen data som følger:

 EA 09 014C010015 1A000000 <- Type Info 0x14c (332) “DateTime2”, 0x15 (21) “DateTime” + Offsetf0 09 6400610074006500740069006d0065003200 <- NAME "DATETIME2" EF 000001 - skriv info7E 02978924A9380B <- "2014-06-18T06:39:05.190"F7 <- afsluttende tag

På denne måde konverterer serveren de lagrede data til typer specificeret i tillægget til denne artikel (du kan se listen over alle datatyper ved at køre "select * from sys.xml_schema_types"-forespørgslen på serveren).

Lad os tage et kig på, hvordan serveren gemmer en mere kompleks struktur, der ligner den i eksempel 1 og beskrevet med XML Schema Collection.

Eksempel 3.

OPRET XML-SKEMA-SAMLING [XmlValuesSchemaCollection] AS'          '; GÅ OPRET TABEL XmlValuesTable ( [uid] [int] IDENTITY PRIMARY KEY, v XML(XmlValuesSchemaCollection) NOT NULL);GOINSERT INTO XmlValuesTable (v)VALUES ('123.456');

Serveren gemmer indsættelsen data som følger:

 EA 05 0001000100 <- Type Infof0 04 6E006F0074006500 <- Navn "Bemærk" EF 000001 <- NamespaceF8 01 <- Tag 01ea 09 01100000011 1200000000 <- Type Info 0x11 (17) "Float" + Offsetf0 05 66006c006f0061007400 <- navn " float"EF 000002 <- NamespaceF8 02 <- tag 02EA 05 0011000011 <- type info 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- closing tagEA 09 001x (09 001 06 02 06) info " + offsetF0 04 740069006D006500 <- Navn "tid"EF 000003 <- NamespaceF8 03 <- tag 03EA 05 0016000016 <- type info 0x16 (22) "time"7D 003FDAF"-71CDAF"7D 003FDAF"-703FDAF"-703FDAFs 7D 003FDAF:71C:70FDAF 7D 003FDAF-703FDAF 7D 003FDAF-703FDAFs 7D 003FDAF. <- afsluttende tag

Lad os prøve at tilføje et skemalink til indsættelsen.

Eksempel 4.

INSERT INTO XmlValuesTable (v)VALUES ('123.456');
 EA 05 0001000100 <- Type Infof0 04 6E006F0074006500 <- Navn "Bemærk" EF 000001 <- NamespaceF8 01 <- Tag 01f0 09 78006d006c006e0073003a00780073006900 <- navn "xmlns:xsi" ef 0002003003a0073006900 <- 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 <- closing tagEA 69 0001 type info 69 0001 (09 001) time" + offsetF0 04 740069006D006500 <- Navn "time"EF 000004 <- NamespaceF8 04 <- tag 08EA 05 0016000016 <- type info 0x16 (22) "time"7D 03F03F 7D 05-09F 7D 03F 09B 7D 03F 03F 7D 7D 03F 03F 7F 7D 03F 03F 7D <7D 03F 03F 03F 8F <7D 03F 03F 8F 7D 03F 03F 03F 03F 03F 05 03 F tagF7 <- afsluttende tag

Som du kan se, har serveren omhyggeligt gemt navneområdet som en attribut og brugt næsten halvdelen af ​​pladsen til dette, selv på trods af at navnerummet ikke rigtig tjener noget brugbart formål her – dataene blev gemt på samme måde som de ville være. gemt uden navneområdet.

Konklusion

Ud fra ovenstående kan det se ud til, at du kan reducere størrelsen på en database ved at gemme nogle datatyper (f.eks. float) som indtastede værdier, da 4 bytes kræver væsentlig mindre lagring end den samme værdi gemt som en Unicode-streng. Du skal dog huske på, at der bruges yderligere 7-18 bytes for hver værdi til at beskrive dens type og flytte den til den nødvendige position.

Tillæg

Korrelation af XML-typer, basistyper og datatyper, som serveren bruger til at gemme indtastede værdier.

XML-type Basistype Gemt som type Størrelse i bytes
anyType streng 2 * tegn
anySimpleType enhverType streng
streng anySimpleType streng
boolesk anySimpleType boolesk 1
flyde anySimpleType flyde 4
dobbelt anySimpleType dobbelt 8
decimal anySimpleType SqlDecimal 20
varighed anySimpleType streng
dateTime anySimpleType *1
tid anySimpleType *1
dato anySimpleType *1
gYearMonth anySimpleType streng
gÅr anySimpleType streng
gMonthDay anySimpleType streng
gDay anySimpleType streng
gMonth anySimpleType streng
hexBinary anySimpleType array af bytes
base64Binary anySimpleType array af bytes
anyURI anySimpleType streng
QName anySimpleType streng
normalizedString streng streng
token streng streng
sprog streng streng
Navn streng streng
NCName streng streng
ENTITY streng streng
NMTOKEN streng streng
heltal decimal SqlDecimal 20
ikke-positivt heltal heltal SqlDecimal 20
negativt heltal ikke-positivt heltal SqlDecimal 20
lang heltal SqlDecimal 20
int lang SqlDecimal 20
kort int SqlDecimal 20
byte kort SqlDecimal 20
nonNegativeInteger heltal SqlDecimal 20
unsignedLong ikke-NegativeInteger SqlDecimal 20
unsignedInt unsignedLong SqlDecimal 20
unsignedShort unsignedInt SqlDecimal 20
unsignedByte unsignedShort SqlDecimal 20
positivt heltal ikke-NegativeInteger SqlDecimal 20
char streng streng
nchar streng streng
varchar streng streng
nvarchar streng streng
tekst streng streng
ntekst streng streng
varbinær base64Binær array af bytes
binær base64Binær array af bytes
billede base64Binær array af bytes
tidsstempel base64Binær array af bytes
timestampNumeric lang SqlDecimal 20
numerisk decimal SqlDecimal 20
bigint lang SqlDecimal 20
smallint kort SqlDecimal 20
tinyint unsignedByte SqlDecimal 20
bit boolesk boolesk 1
rigtig flyde flyde 4
datotid datoTid *1
smalldatetime datoTid *1
penge decimal SqlDecimal
småpenge decimal SqlDecimal
uniqueidentifier decimal streng
datetime2 datoTid *1
datetime offset datoTid *1
hierarchyid streng streng
dbobject anyURI streng

*1 – data/tidsoplysninger. Den specifikke type er defineret af værdien.

Værdi Gemt som type Størrelse i bytes
Datoforskydning Dato (antal dage) 3
Datoforskydning (2019-09-16+02:00) DatoTimeOffset 11
DatoTid DatoTid 7-9 afhænger af præcision
DatoTimeOffset DatoTimeOffset 9
Tid DatoTid 7-9 afhænger af præcision
Tidsforskydning (01:23:45Z) DatoTimeOffset 9

  1. Markørbaserede poster i PostgreSQL

  2. PHP mysql indsæt datoformat

  3. Lær at gemme og analysere dokumenter på Windows filsystem med SQL Server Semantic Search – Del 1

  4. returnere resultatsæt fra funktion