sql >> Databáze >  >> RDS >> Sqlserver

Ukládání dat XML na SQL Server

Při práci na vydání dbForge Transaction Log, mimo jiné, musel náš tým vyřešit, jak správně ukládat zadaná XML data.

Pro začátek stojí za zmínku, že SQL Server neukládá XML ve formátu, ve kterém byl zadán. Řetězec XML je analyzován, rozdělen na značky, a proto je uložen v komprimovaném formátu. Prvky popisu, které server považuje za nepotřebné, jsou vyřazeny.

Je také třeba mít na paměti, že pokud je datový typ sloupce zadán jako jednoduchý XML, server tato data uloží jako řetězce Unicode.
Příklad 1.

CREATE TABLE XmlValuesTable ( [uid] [int] PRIMÁRNÍ KLÍČ IDENTITY, v XML NOT NULL );GOINSERT INTO XmlValuesTable (v)VALUES ('123.456');INSERT INTO XmlValuesTable (v)VALUES ('4,0000000000');

Server uloží vložení údaje takto:

F0 04 6E006F0074006500 <- Jméno "Poznámka" EF 000001 <- Jméno na jmenii 01F8 01 <- TAG 01F0 05 66006C006F0061007400 <- Jméno "Float" EF 000002 <- JMDYPACE 02F8 02 <- Tag 0211 07 F7 <- uzavírací tagF0 04 740069006D006500 <- Název "time"EF 000003 <- Jmenný prostor 02F8 03 <- tag 0311 0C 300031003A00320033003A0032E0035 <03>uzavírací řetězec V následujícím příkladu je datový typ sloupce zadán jako zadaný prostřednictvím kolekce schémat XML.

Příklad 2.

VYTVOŘTE KOLEKCI SCHÉMATU XML [XmlValuesSchemaCollection_datetime2] AS'  ';GOCREATE TABLE XmlValuesTable_datetime2 ( [uid] [ int] PRIMÁRNÍ KLÍČ IDENTITY, v XML(XmlValuesSchemaCollection_datetime2) NOT NULL);GOINSERT INTO XmlValuesTable_datetime2 (v)VALUES (N'2014-06-18T06:39:05.190'); 

V tomto konkrétním případě server uloží vložení údaje takto:

ea 09 014C010015 1A000000 <- typ info 0x14c (332) „DateTime2“, 0x15 (21) „DateTime“ + offsetf0 09 6400610074006500740069006d00665200 <- Jméno „DatEtime2“ - zadejte info7E 02978924A9380B <- "2014-06-18T06:39:05.190"F7 <- uzavírací značka

Tímto způsobem server převede uložená data na typy specifikované v dodatku k tomuto článku (seznam všech datových typů můžete zobrazit spuštěním dotazu „select * from sys.xml_schema_types“ na serveru).

Pojďme se podívat na to, jak server uloží složitější strukturu podobnou té v příkladu 1 a popsané pomocí XML Schema Collection.

Příklad 3.

VYTVOŘTE KOLEKCI SCHÉMŮ XML [XmlValuesSchemaCollection] AS'          '; GO CREATE TABLE XmlValuesTable ( [uid] [int] PRIMÁRNÍ KLÍČ IDENTITY, v XML(XmlValuesSchemaCollection) NOT NULL);GOINSERT INTO XmlValuesTable (v)VALUES ('123,456');

Server uloží vložení údaje takto:

EA 05 0001000100 <- typ infoF0 04 6E006F0074006500 <- Název "note"EF 000001 <- Jmenný prostorF8 01 <- tag 01EA 09 0111000011 01001012000011 01200001061200001060120000106 float"EF 000002 <- NamespaceF8 02 <- tag 02EA 05 0011000011 <- info typu 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- uzavírací tagEA 09 0116 000x "čas ukončení 06 0116 000x" " + offsetF0 04 740069006D006500 <- Název "time"EF 000003 <- NamespaceF8 03 <- tag 03EA 05 0016000016 <- info typu 0x16 (22) "time"7D 03FDAF95001 "tag"  

Zkusme do přílohy přidat odkaz na schéma.

Příklad 4.

INSERT INTO XmlValuesTable (v)VALUES ('123,456');
ea 05 0001000100 <- typ infof0 04 6e006f0074006500 <- name "note" ef 000001 <- namespacef8 01 <- značka 01f0 09 78006d006c006e0073003a0078003006900 <- jméno "xMlns:xsis" ef rtys-názvy "° C" ef ° C "ef ° C" ef " <- 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 <- info typu 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- uzavírací tag 0009 <016160009 <016160000 time" + offsetF0 04 740069006D006500 <- Název "time"EF 000004 <- NamespaceF8 04 <- tag 08EA 05 0016000016 <- info typu 0x16 (22) "time"7D 07FDAF94C07 "uzavírka" tagF7 <- uzavírací značka

Jak vidíte, server pečlivě uložil jmenný prostor jako atribut a využil k tomu téměř polovinu místa, přestože zde jmenný prostor neslouží vlastně k žádnému užitečnému účelu – data byla uložena stejným způsobem. uloženo bez jmenného prostoru.

Závěr

Z výše uvedeného se může zdát, že můžete zmenšit velikost databáze uložením některých datových typů (např. float) jako typizovaných hodnot, protože 4 bajty vyžadují podstatně méně místa než stejná hodnota uložená jako řetězec Unicode. Měli byste však mít na paměti, že pro každou hodnotu se používá dalších 7–18 bajtů k popisu jejího typu a přesunutí na potřebnou pozici.

Dodatek

Korelace typů XML, základních typů a datových typů, které server používá k ukládání zadaných hodnot.

Typ XML Typ základny Uloženo jako typ Velikost v bajtech
jakýkoliTyp řetězec 2 * znaky
anySimpleType jakýkoliTyp řetězec
řetězec anySimpleType řetězec
logická hodnota anySimpleType logická hodnota 1
plovoucí anySimpleType plovoucí 4
double anySimpleType double 8
desítkové anySimpleType SqlDecimal 20
trvání anySimpleType řetězec
dateTime anySimpleType *1
čas anySimpleType *1
datum anySimpleType *1
gYearMonth anySimpleType řetězec
gYear anySimpleType řetězec
gMonthDay anySimpleType řetězec
gDay anySimpleType řetězec
gMonth anySimpleType řetězec
hexBinary anySimpleType pole bajtů
base64Binary anySimpleType pole bajtů
jakékoli URI anySimpleType řetězec
QName anySimpleType řetězec
normalizedString řetězec řetězec
token řetězec řetězec
jazyk řetězec řetězec
Jméno řetězec řetězec
NCName řetězec řetězec
ENTITY řetězec řetězec
NMTOKEN řetězec řetězec
celé číslo desítkové SqlDecimal 20
nonPositiveInteger celé číslo SqlDecimal 20
negativeInteger nonPositiveInteger SqlDecimal 20
dlouhé celé číslo SqlDecimal 20
int dlouhé SqlDecimal 20
krátký int SqlDecimal 20
bajt krátké SqlDecimal 20
nonNegativeInteger celé číslo SqlDecimal 20
unsignedLong nonNegativeInteger SqlDecimal 20
unsignedInt unsignedLong SqlDecimal 20
unsignedShort unsignedInt SqlDecimal 20
unsignedByte unsignedShort SqlDecimal 20
positiveInteger nonNegativeInteger SqlDecimal 20
char řetězec řetězec
nchar řetězec řetězec
varchar řetězec řetězec
nvarchar řetězec řetězec
text řetězec řetězec
ntext řetězec řetězec
varbinární base64Binary pole bajtů
binární base64Binary pole bajtů
obrázek base64Binary pole bajtů
časové razítko base64Binary pole bajtů
timestampNumeric dlouhé SqlDecimal 20
numerické desítkové SqlDecimal 20
bigint dlouhé SqlDecimal 20
smallint krátké SqlDecimal 20
tinyint unsignedByte SqlDecimal 20
bit logická hodnota logická hodnota 1
skutečný plovoucí plovoucí 4
datetime dateTime *1
smalldatetime dateTime *1
peníze desítkové SqlDecimal
malé peníze desítkové SqlDecimal
jedinečný identifikátor desítkové řetězec
datetime2 dateTime *1
datetimeoffset dateTime *1
hierarchyid řetězec řetězec
dbobject jakékoli URI řetězec

*1 – údaje/časové informace. Konkrétní typ je definován hodnotou.

Hodnota Uloženo jako typ Velikost v bajtech
DateOffset Datum (počet dní) 3
Posun data (2019-09-16+02:00) DateTimeOffset 11
Datum a čas Datum a čas 7-9 závisí na přesnosti
DateTimeOffset DateTimeOffset 9
Čas Datum a čas 7-9 závisí na přesnosti
Časový posun (01:23:45 Z) DateTimeOffset 9

  1. Alternativa funkce lead lag v SQL Server 2008

  2. Jak převést DateTime na VarChar

  3. Doporučené procesory Intel pro SQL Server 2014 – březen 2015

  4. Použití SELECT INTO OUTFILE v MySQL