Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Menyimpan data XML di SQL Server

Saat mengerjakan rilis Log Transaksi dbForge, di antara tugas-tugas lainnya, tim kami harus memikirkan cara menyimpan data XML yang diketik dengan benar.

Untuk memulainya, perlu disebutkan bahwa SQL Server tidak menyimpan XML dalam format yang dimasukkan. String XML diuraikan, dipisah menjadi tag, dan dengan demikian disimpan dalam format terkompresi. Elemen deskripsi yang dianggap tidak perlu oleh server akan dibuang.

Perlu diingat juga bahwa, jika tipe data kolom ditetapkan sebagai XML sederhana, server akan menyimpan data ini sebagai string Unicode.
Contoh 1.

CREATE TABLE XmlValuesTable (
  [uid] [int] IDENTITY PRIMARY KEY,
  v XML NOT NULL );
GO
INSERT INTO XmlValuesTable (v)
VALUES ('<note><float>123.456</float><time>01:23:45.789</time></note>');
INSERT INTO XmlValuesTable (v)
VALUES ('<note><float>4.0000000000</float><time>01:23:45Z</time></note>');

Server akan menyimpan insert datanya sebagai berikut:

F0 04 6E006F0074006500 <- Name "note"
EF 000001 <- Namespace 01
F8 01 <- tag 01
F0 05 66006C006F0061007400 <- Name "float"
EF 000002 <- Namespace 02
F8 02 <- tag 02
11 07 3100320033002E00340035003600 <- string "123.456"
F7 <- closing tag
F0 04 740069006D006500 <- Name "time"
EF 000003 <- Namespace 02
F8 03 <- tag 03
11 0C 300031003A00320033003A00340035002E00370038003900 <- string "01:23:45.789"
F7 <- closing tag
F7 <- closing tag

Dalam contoh berikut, tipe data kolom ditentukan sebagai yang diketik melalui XML Schema Collection.

Contoh 2.

CREATE XML SCHEMA COLLECTION [XmlValuesSchemaCollection_datetime2] AS
'<?xml version="1.0"?> 
<xsd:schema
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes"

  <xsd:element name="datetime2" type="sqltypes:datetime2"/> 
</xsd:schema>';
GO

CREATE TABLE XmlValuesTable_datetime2 (
  [uid] [int] IDENTITY PRIMARY KEY,
  v XML(XmlValuesSchemaCollection_datetime2) NOT NULL
);
GO

INSERT INTO XmlValuesTable_datetime2 (v)
VALUES (N'<datetime2>2014-06-18T06:39:05.190</datetime2>');
GO

Dalam kasus khusus ini, server akan menyimpan insert datanya sebagai berikut:

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

Dengan cara ini, server mengonversi data yang disimpan ke tipe yang ditentukan dalam adendum artikel ini (Anda dapat melihat daftar semua tipe data dengan menjalankan kueri “pilih * dari sys.xml_schema_types” di server).

Mari kita lihat bagaimana server akan menyimpan struktur yang lebih kompleks mirip dengan yang ada di Contoh 1 dan dijelaskan dengan XML Schema Collection.

Contoh 3.

CREATE XML SCHEMA COLLECTION [XmlValuesSchemaCollection] AS
'<?xml version="1.0"?>
<xsd:schema
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes"
  attributeFormDefault="unqualified" elementFormDefault="qualified"> 
  <xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes"
schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sql2008/sqltypes.xsd"/>

    <xsd:element name="note"> 
     <xsd:complexType> 
       <xsd:sequence> 
          <xsd:element name="float" type="xsd:float"/> 
          <xsd:element name="time" type="xsd:time"/> 
       </xsd:sequence> 
     </xsd:complexType> 
  </xsd:element> 
</xsd:schema>'; 
GO 

CREATE TABLE XmlValuesTable (
  [uid] [int] IDENTITY PRIMARY KEY,
  v XML(XmlValuesSchemaCollection) NOT NULL
);
GO

INSERT INTO XmlValuesTable (v)
VALUES ('<note><float>123.456</float><time>01:23:45.789</time></note>');

Server akan menyimpan insert datanya sebagai berikut:

EA 05 0001000100 <- type info
F0 04 6E006F0074006500 <- Name "note"
EF 000001 <- Namespace
F8 01 <- tag 01
EA 09 0111000011 12000000 <- type info 0x11 (17) "float" + offset
F0 05 66006C006F0061007400 <- Name "float"
EF 000002 <- Namespace
F8 02 <- tag 02
EA 05 0011000011 <- type info 0x11 (17) "float"
03 79E9F642 <- "123.456"
F7 <- closing tag
EA 09 0116000016 10000000 <- type info 0x16 (22) "time" + offset
F0 04 740069006D006500 <- Name "time"
EF 000003 <- Namespace
F8 03 <- tag 03
EA 05 0016000016 <- type info 0x16 (22) "time"
7D 03FDAF4C005B950A <- "01:23:45.789"
F7 <- closing tag
F7 <- closing tag

Mari kita coba menambahkan tautan skema ke sisipan.

Contoh 4.

INSERT INTO XmlValuesTable (v)
VALUES ('<note xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><float>123.456</float><time>01:23:45.789</time></note>');
EA 05 0001000100 <- type info
F0 04 6E006F0074006500 <- Name "note"
EF 000001 <- Namespace
F8 01 <- tag 01
F0 09 78006D006C006E0073003A00780073006900 <- Name "xmlns:xsi"
EF 000200 <- Namespace "xmlns:xsi"
F6 02 <- Attribute
11 29 68007400740070003A002F002F007700770077002E00770033002E006F00720067002F0032003000300031002F0058004D004C0053006300680065006D0061002D0069006E007300740061006E0063006500 <- "http://www.w3.org/2001/XMLSchema-instance"
F5 <- closing bracket
EA 09 0111000011 12000000 <- type info 0x11 (17) "float" + offset
F0 05 66006C006F0061007400 <- Name "float"
EF 000003 <- Namespace
F8 03 <- tag 03
EA 05 0011000011 <- type info 0x11 (17) "float"
03 79E9F642 <- "123.456"
F7 <- closing tag
EA 09 0116000016 10000000 <- type info 0x16 (22) "time" + offset
F0 04 740069006D006500  <- Name "time"
EF 000004 <- Namespace
F8 04 <- tag 08
EA 05 0016000016 <- type info 0x16 (22) "time"
7D 03FDAF4C005B950A <- "01:23:45.789"
F7 <- closing tag
F7 <- closing tag

Seperti yang Anda lihat, server telah dengan hati-hati menyimpan namespace sebagai atribut dan menggunakan hampir setengah ruang untuk ini meskipun faktanya namespace tidak benar-benar melayani tujuan yang berguna di sini – data disimpan dengan cara yang sama. disimpan tanpa namespace.

Kesimpulan

Dari penjelasan di atas, tampaknya Anda dapat mengurangi ukuran database dengan menyimpan beberapa tipe data (misalnya float) sebagai nilai yang diketik karena 4 byte memerlukan penyimpanan yang jauh lebih sedikit daripada nilai yang sama yang disimpan sebagai string Unicode. Namun, Anda harus ingat bahwa tambahan 7-18 byte digunakan untuk setiap nilai untuk menjelaskan jenisnya dan memindahkannya ke posisi yang diperlukan.

tambahan

Korelasi tipe XML, tipe dasar, dan tipe data yang digunakan server untuk menyimpan nilai yang diketik.

Jenis XML Tipe dasar Disimpan sebagai jenis Ukuran dalam byte
jenis apa saja string 2 * karakter
anySimpleType jenis apa saja string
string anySimpleType string
boolean anySimpleType boolean 1
mengambang anySimpleType mengambang 4
dua kali lipat anySimpleType ganda 8
desimal anySimpleType SqlDesimal 20
durasi anySimpleType string
tanggalWaktu anySimpleType *1
waktu anySimpleType *1
tanggal anySimpleType *1
gTahunBulan anySimpleType string
gTahun anySimpleType string
gBulanHari anySimpleType string
gDay anySimpleType string
gBulan anySimpleType string
hexBinary anySimpleType array byte
base64Binary anySimpleType array byte
anyURI anySimpleType string
QName anySimpleType string
normalisasiString string string
token string string
bahasa string string
Nama string string
NCName string string
ENTITAS string string
NMTOKEN string string
bilangan bulat desimal SqlDesimal 20
nonPositiveInteger bilangan bulat SqlDesimal 20
bilangan bulat negatif nonPositiveInteger SqlDesimal 20
panjang bilangan bulat SqlDesimal 20
int panjang SqlDesimal 20
pendek int SqlDesimal 20
byte pendek SqlDesimal 20
nonNegativeInteger bilangan bulat SqlDesimal 20
unsignedLong nonNegativeInteger SqlDesimal 20
unsignedInt unsignedLong SqlDesimal 20
unsignedShort unsignedInt SqlDesimal 20
unsignedByte unsignedShort SqlDesimal 20
Integer positif nonNegativeInteger SqlDesimal 20
chart string string
nchar string string
varchar string string
nvarchar string string
teks string string
nteks string string
varbiner base64Binary array byte
biner base64Binary array byte
gambar base64Binary array byte
stempel waktu base64Binary array byte
timestampNumeric panjang SqlDesimal 20
numerik desimal SqlDesimal 20
besar panjang SqlDesimal 20
kecil pendek SqlDesimal 20
kecil unsignedByte SqlDesimal 20
sedikit boolean boolean 1
nyata mengambang mengambang 4
waktu tanggal tanggalWaktu *1
waktu kecil tanggalWaktu *1
uang desimal SqlDesimal
uang kecil desimal SqlDesimal
pengidentifikasi unik desimal string
datetime2 tanggalWaktu *1
datetimeoffset tanggalWaktu *1
hierarkiid string string
dbobject anyURI string

*1 – informasi data/waktu. Jenis spesifik ditentukan oleh nilainya.

Nilai Disimpan sebagai jenis Ukuran dalam byte
TanggalOffset Tanggal (jumlah hari) 3
DateOffset (2019-09-16+02:00) DateTimeOffset 11
TanggalWaktu TanggalWaktu 7-9 tergantung dari presisi
DateTimeOffset DateTimeOffset 9
Waktu TanggalWaktu 7-9 tergantung dari presisi
Offset Waktu (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. Pengenalan SQL Server

  2. TAN() Contoh di SQL Server

  3. SQL Server mengonversi varbinary ke string

  4. Dapatkan hari pertama dalam seminggu di SQL Server

  5. Apa cara terbaik untuk mengontrol versi prosedur tersimpan server SQL saya?