sql >> Databasteknik >  >> RDS >> Sqlserver

Lagring av XML-data i SQL Server

När vi arbetade med lanseringen av dbForge Transaction Log, bland andra uppgifter, var vårt team tvungen att pussla ut hur man korrekt lagrar inskriven XML-data.

Till att börja med är det värt att nämna att SQL Server inte lagrar XML i det format som den angavs. En XML-sträng tolkas, delas upp till taggar och lagras därför i ett komprimerat format. Beskrivningselement som servern anser vara onödiga kasseras.

Det bör också komma ihåg att om datatypen för en kolumn anges som enkel XML, kommer servern att lagra denna data som Unicode-strängar.
Exempel 1.

SKAPA TABELL XmlValuesTable ( [uid] [int] IDENTITETSPRIMÄRKEY, v XML NOT NULL );GOINSERT INTO XmlValuesTable (v)VALUES ('123.456');INSERT INTO XmlValuesTable (v)VALUES ('4.0000000000');

Servern kommer att lagra insert data enligt följande:

 F0 04 6E006F0074006500 <- NAME "Obs" EF 000001 <- NAMESPACE 01F8 01 <- TAG 01F0 05 66006C006F0061007400 <- NAMN "FLOAT" EF 000002 <- NAMESPACE 02F8 02 <-TAG 0211 07 31300300330033003030020020030300 " F7 <- Stängning TAGF0 04 740069006D006500 <- NAME "TIME" EF 000003 <- NAMESPACE 02F8 03 <- TAG 0311 0C 300031003A00320033003A00340035002E00370038003900 <- String "01:23:23:45.7" FAGFING Tagga 

I följande exempel anges kolumndatatypen som den har skrivits genom XML Schema Collection.

Exempel 2.

SKAPA XML-SCHEMA KOLLEKTION [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 

I det här specifika fallet kommer servern att lagra insert data enligt följande:

EA 09 014C010015 1A000000 <- type info 0x14C (332) “datetime2”, 0x15 (21) “dateTime” + offsetF0 09 6400610074006500740069006D0065003200 <- Name "datetime2"EF 000001 <- Namespace 01F8 01 <- tag 01EA 05 004C010015 <- typ info7E 02978924A9380B <- "2014-06-18T06:39:05.190"F7 <- avslutande tag

På detta sätt konverterar servern lagrad data till typer som anges i tillägget till denna artikel (du kan se listan över alla datatyper genom att köra "select * from sys.xml_schema_types"-frågan på servern).

Låt oss ta en titt på hur servern kommer att spara en mer komplex struktur som liknar den i exempel 1 och som beskrivs med XML Schema Collection.

Exempel 3.

SKAPA XML-SCHEMA KOLLEKTION [XmlValuesSchemaCollection] AS'          '; GÅ SKAPA TABELL XmlValuesTable ( [uid] [int] IDENTITY PRIMARY KEY, v XML(XmlValuesSchemaCollection) NOT NULL);GOINSERT INTO XmlValuesTable (v)VALUES ('123.456');

Servern sparar inlägget data enligt följande:

EA 05 0001000100 <- type infoF0 04 6E006F0074006500 <- Name "note"EF 000001 <- NamespaceF8 01 <- tag 01EA 09 0111000011 12000000 <- type info 0x11 (17) "float" + offsetF0 05 66006C006F0061007400 <- Name " float"EF 000002 <- NamnutrymmeF8 02 <- tag 02EA 05 0011000011 <- typ info 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- stängningstaggEA 609 001 0206 typ 09 001 02 06 001 06 001 0006 " + offsetF0 04 740069006D006500 <- Namn "tid"EF 000003 <- NamnutrymmeF8 03 <- tagg 03EA 05 0016000016 <- typinfo 0x16 (22) "tid"7D 003FDAF"-703FDAF 7D 003FDAF"-703FDAF 7D 003FDAF"-703FDAF 7D 003FDAF 7D 003FDAF 7F 703FDAF 7D 003FDAF:71C:71C:71C:71C:70FDAF <- avslutande tag

Låt oss försöka lägga till en schemalänk till bilagan.

Exempel 4.

INSERT INTO XmlValuesTable (v)VALUES ('123.456');
 ea 05 0001000100 <- Typ InfoF0 04 6E006F0074006500 <- NAME "Obs" EF 000001 <- NAMESPACEF8 01 <- TAG 01F0 09 78006D006C006E0073003A007880073006900 <- 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 <- NamnutrymmeF8 03 <- tag 03EA 05 0011000011 <- typ info 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- avslutande tagEA 69 0001 typ 69 0001 (01002) typ time" + offsetF0 04 740069006D006500 <- Namn "time"EF 000004 <- NamespaceF8 04 <- tag 08EA 05 0016000016 <- typ info 0x16 (22) "time"7D 03F01 "closing" 5C03F:-7F 7D 03F 03F:A <05-09F:A <05-09F:A <5C03F:A <05-09F. tagF7 <- avslutande tagg

Som du kan se har servern noggrant sparat namnutrymmet som ett attribut och använt nästan halva utrymmet för detta även trots att namnområdet egentligen inte tjänar något användbart syfte här – data sparades på samma sätt som det skulle vara sparas utan namnutrymmet.

Slutsats

Av ovanstående kan det tyckas att du kan minska storleken på en databas genom att lagra vissa datatyper (t.ex. float) som inskrivna värden eftersom 4 byte kräver betydligt mindre lagring än samma värde som sparats som en Unicode-sträng. Du bör dock komma ihåg att ytterligare 7-18 byte används för varje värde för att beskriva dess typ och flytta det till den nödvändiga positionen.

Tillägg

Korrelation mellan XML-typer, bastyper och datatyper som servern använder för att lagra inskrivna värden.

XML-typ Bastyp Lagrade som typ Storlek i byte
anyType sträng 2 * tecken
anySimpleType anyType sträng
sträng anySimpleType sträng
boolesk anySimpleType booleskt 1
flyta anySimpleType flyta 4
dubbel anySimpleType dubbel 8
decimal anySimpleType SqlDecimal 20
varaktighet anySimpleType sträng
dateTime anySimpleType *1
tid anySimpleType *1
datum anySimpleType *1
gYearMonth anySimpleType sträng
gÅr anySimpleType sträng
gMonthDay anySimpleType sträng
gDay anySimpleType sträng
gMonth anySimpleType sträng
hexBinary anySimpleType array av byte
base64Binary anySimpleType array av byte
anyURI anySimpleType sträng
QName anySimpleType sträng
normalizedString sträng sträng
token sträng sträng
språk sträng sträng
Namn sträng sträng
NCName sträng sträng
ENTITY sträng sträng
NMTOKEN sträng sträng
heltal decimal SqlDecimal 20
icke-positivt heltal heltal SqlDecimal 20
negativt heltal icke-positivt heltal SqlDecimal 20
lång heltal SqlDecimal 20
int lång SqlDecimal 20
kort int SqlDecimal 20
byte kort SqlDecimal 20
ickeNegativeInteger heltal SqlDecimal 20
unsignedLong ickeNegativeInteger SqlDecimal 20
unsignedInt unsignedLong SqlDecimal 20
unsignedShort unsignedInt SqlDecimal 20
unsignedByte unsignedShort SqlDecimal 20
positivt heltal ickeNegativeInteger SqlDecimal 20
char sträng sträng
nchar sträng sträng
varchar sträng sträng
nvarchar sträng sträng
text sträng sträng
ntext sträng sträng
varbinary base64Binary array av byte
binär base64Binary array av byte
bild base64Binary array av byte
tidsstämpel base64Binary array av byte
timestampNumeric lång SqlDecimal 20
numerisk decimal SqlDecimal 20
bigint lång SqlDecimal 20
smallint kort SqlDecimal 20
tinyint unsignedByte SqlDecimal 20
bit booleskt booleskt 1
riktigt flyta flyta 4
datumtid dateTime *1
smalldatetime dateTime *1
pengar decimal SqlDecimal
småpengar decimal SqlDecimal
uniqueidentifier decimal sträng
datetime2 dateTime *1
datetime offset dateTime *1
hierarchyid sträng sträng
dbobject anyURI sträng

*1 – data/tidsinformation. Den specifika typen definieras av värdet.

Värde Lagrade som typ Storlek i byte
DatumOffset Datum (antal dagar) 3
DatumOffset (2019-09-16+02:00) DateTimeOffset 11
DatumTime DatumTid 7-9 beror på precision
DateTimeOffset DateTimeOffset 9
Tid DatumTid 7-9 beror på precision
Tidsförskjutning (01:23:45Z) DateTimeOffset 9

  1. Gruppera efter alias (Oracle)

  2. Implementera Switchover/Switchback i PostgreSQL 9.3.

  3. Hur STRCMP() fungerar i MariaDB

  4. Hur man får första posten i varje grupp i MySQL