Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Съхранение на XML данни в SQL Server

Когато работехме по пускането на dbForge Transaction Log, наред с други задачи, нашият екип трябваше да озадачи как правилно да съхранява въведени XML данни.

Като начало си струва да споменем, че SQL Server не съхранява XML във формата, в който е въведен. XML низ се анализира, разделя на тагове и по този начин се съхранява в компресиран формат. Елементите на описанието, които сървърът счита за ненужни, се отхвърлят.

Също така трябва да се има предвид, че ако типът данни на колона е посочен като прост XML, сървърът ще съхранява тези данни като Unicode низове.
Пример 1.

СЪЗДАДЕТЕ ТАБЛИЦА XmlValuesTable ( [uid] [int] ПЪРВИЧЕН КЛЮЧ НА ИДЕНТИЧНОСТ, v XML NOT NULL );ВЪВЕДЕТЕ В XmlValuesTable (v) VALUES ('123.456');ВМЕСЕТЕ В XmlValuesTable (v)VALUES ('4.0000000000');

Сървърът ще съхранява вмъкването данни, както следва:

 f0 04 6e006f0074006500 <- Име "Забележка" EF 000001 <- Пространство на имена 01F8 01 <- TAG 01F0 05 66006C006F0061007400 <- Име "Float" EF 000002 <- Namesspace 02F8 02 <- TAG 0211 07 3100320033002e F7 <- Closing TAGF0 04 740069006D006500 <- Име "Време" EF 000003 <- пространство на имена 02F8 03 <- TAG 0311 0C 300031003A00320033003A00340035002E00370038003900 
 В следващия пример типът данни на колоната е посочен така, както е въведен чрез XML Schema Collection.

Пример 2.

СЪЗДАВАНЕ НА КОЛЕКЦИЯ ЗА XML СХЕМА [XmlValuesSchemaCollection_datetime2] КАТО  ';GOCREATE TABLE XmlValuesTable_datetime2 ( [uid] [ int] ПЪРВИЧЕН КЛЮЧ НА ИДЕНТИФИКАЦИЯ, v XML(XmlValuesSchemaCollection_datetime2) НЕ НУЛЕВО);ВЪВЕДЕТЕ В XmlValuesTable_datetime2 (v)VALUES (N'2014-06-18T06:39:05);. 

В този конкретен случай сървърът ще съхранява вмъкването данни, както следва:

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 <- въведете info7E 02978924A9380B <- "2014-06-18T06:39:05.190"F7 <- затварящ маркер

По този начин сървърът преобразува съхранените данни в типове, посочени в допълнението към тази статия (можете да видите списъка с всички типове данни, като изпълните заявката „select * from sys.xml_schema_types“ на сървъра).

Нека да разгледаме как сървърът ще запази по-сложна структура, подобна на тази в Пример 1 и описана с XML Schema Collection.

Пример 3.

СЪЗДАВАНЕ НА КОЛЕКЦИЯ ЗА XML SCHEMA [XmlValuesSchemaCollection] КАТО          '; СЪЗДАВАЙТЕ ТАБЛИЦА XmlValuesTable ( [uid] [int] ПЪРВИЧЕН КЛЮЧ НА ИДЕНТИФИКАЦИЯ, v XML(XmlValuesSchemaCollection) НЕ NULL); ВЪВЕЖЕТЕ В XmlValuesTable (v) VALUES ('123.456<500:23.456 :45,789');

Сървърът ще запази вмъкването данни, както следва:

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 <- NamespaceF8 02 <- tag 02EA 05 0011000011 <- тип информация 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- затварящ етикет тип EA6 09 01 
информация 09 001 " + offsetF0 04 740069006D006500 <- Име "time"EF 000003 <- NamespaceF8 03 <- tag 03EA 05 0016000016 <- тип информация 0x16 (22) "time"7D 03FDAB9C tag:03FDAB9F07":<- затварящ маркер

Нека опитаме да добавим връзка към схемата към вмъкването.

Пример 4.

INSERT INTO XmlValuesTable (v)VALUES ('123.456');
 EA 05 0001000100 <- Тип infof0 04 6e006f0074006500 <- Име "Забележка" EF 000001 <- Namespacef8 01 <- Tag 01f0 09 78006d006c006e0073003a00780073006900 <- име "xmln <- 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 <- тип информация 0x11 (17) "float"03 79E9F642 <- "123.456"F7 <- затварящ етикет typeEA 09 01 "09 01 time" + offsetF0 04 740069006D006500 <- Име "time"EF 000004 <- NamespaceF8 04 <- tag 08EA 05 0016000016 <- тип информация 0x16 (22) "time"7D 03FDABF07 "closing":03FDABF05:tagF7 <- затварящ маркер

Както можете да видите, сървърът внимателно е запазил пространството от имена като атрибут и е използвал почти половината пространство за това, дори въпреки факта, че пространството от имена всъщност не служи за полезна цел тук – данните са запазени по същия начин, по който биха били запазено без пространството от имена.

Заключение

От горното може да изглежда, че можете да намалите размера на базата данни, като съхранявате някои типове данни (например float) като въведени стойности, тъй като 4 байта изискват значително по-малко място за съхранение от същата стойност, записана като Unicode низ. Трябва обаче да имате предвид, че за всяка стойност се използват допълнителни 7-18 байта, за да се опише нейния тип и да се премести на необходимата позиция.

Допълнение

Съотношение на XML типове, базови типове и типове данни, които сървърът използва за съхраняване на въведени стойности.

XML тип Базов тип Съхранява се като тип Размер в байтове
anyType низ 2 * знака
anySimpleType anyType низ
низ anySimpleType низ
булева anySimpleType булева 1
float anySimpleType float 4
двойно anySimpleType двойно 8
десетичен знак anySimpleType SqlDecimal 20
продължителност anySimpleType низ
dateTime anySimpleType *1
време anySimpleType *1
дата anySimpleType *1
gYearMonth anySimpleType низ
gГодина anySimpleType низ
gMonthDay anySimpleType низ
gDay anySimpleType низ
gМесец anySimpleType низ
hexBinary anySimpleType Масив от байтове
base64Binary anySimpleType Масив от байтове
който и да е URI anySimpleType низ
QName anySimpleType низ
нормализиран низ низ низ
токен низ низ
език низ низ
Име низ низ
NCName низ низ
ENTITY низ низ
NMTOKEN низ низ
цяло число десетичен знак SqlDecimal 20
неположително цяло число цяло число SqlDecimal 20
отрицателно цяло число неположително цяло число SqlDecimal 20
дълго цяло число SqlDecimal 20
int дълго SqlDecimal 20
кратко int SqlDecimal 20
байт кратко SqlDecimal 20
неотрицателно цяло число цяло число SqlDecimal 20
unsignedLong неотрицателно цяло число SqlDecimal 20
unsignedInt unsignedLong SqlDecimal 20
unsignedShort unsignedInt SqlDecimal 20
unsignedByte unsignedShort SqlDecimal 20
positiveInteger неотрицателно цяло число SqlDecimal 20
char низ низ
nchar низ низ
varchar низ низ
nvarchar низ низ
текст низ низ
ntext низ низ
варбинарен base64Binary Масив от байтове
двоичен base64Binary Масив от байтове
изображение base64Binary Масив от байтове
марка за време base64Binary Масив от байтове
timestampNumeric дълго SqlDecimal 20
числово десетичен знак SqlDecimal 20
голям дълго SqlDecimal 20
smallint кратко SqlDecimal 20
tinyint unsignedByte SqlDecimal 20
бит булева булева 1
истински float float 4
дата и час dateTime *1
smalldatetime dateTime *1
пари десетичен знак SqlDecimal
малки пари десетичен знак SqlDecimal
уникален идентификатор десетичен знак низ
дата и час2 dateTime *1
datetimeoffset dateTime *1
йерархия низ низ
dbobject който и да е URI низ

*1 – информация за данни/време. Конкретният тип се определя от стойността.

Стойност Съхранява се като тип Размер в байтове
Отместване на датата Дата (количество дни) 3
DateOffset (2019-09-16+02:00) DateTimeOffset 11
Дата и час Дата и час 7-9 зависи от точността
DateTimeOffset DateTimeOffset 9
Време Дата и час 7-9 зависи от точността
TimeOffset (01:23:45Z) DateTimeOffset 9

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да вмъкна арабски знаци в SQL база данни?

  2. Конкатениране на много редове в един текстов низ с групиране

  3. Преобразувайте заявката на SQL Server в MySQL

  4. грешка при вмъкване в таблица с вместо задействане от рамката за данни на обекта

  5. Кой синтаксис на присъединяване е по-добър?