Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Lưu trữ dữ liệu XML trong SQL Server

Khi làm việc trên bản phát hành Nhật ký giao dịch dbForge, trong số các nhiệm vụ khác, nhóm của chúng tôi phải tìm cách lưu trữ dữ liệu XML đã nhập đúng cách.

Để bắt đầu, điều đáng nói là SQL Server không lưu trữ XML ở định dạng mà nó đã được nhập. Một chuỗi XML được phân tích cú pháp, phân tách thành các thẻ và do đó được lưu trữ ở định dạng nén. Các phần tử mô tả mà máy chủ cho là không cần thiết sẽ bị loại bỏ.

Cũng cần lưu ý rằng, nếu kiểu dữ liệu của một cột được chỉ định là XML đơn giản, máy chủ sẽ lưu trữ dữ liệu này dưới dạng chuỗi Unicode.
Ví dụ 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>');

Máy chủ sẽ lưu trữ insert dữ liệu như sau:

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

Trong ví dụ sau, kiểu dữ liệu cột được chỉ định như được nhập thông qua Bộ sưu tập lược đồ XML.

Ví dụ 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

Trong trường hợp cụ thể này, máy chủ sẽ lưu trữ insert dữ liệu như sau:

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

Theo cách này, máy chủ chuyển đổi dữ liệu được lưu trữ thành các loại được chỉ định trong phụ lục của bài viết này (bạn có thể xem danh sách tất cả các loại dữ liệu bằng cách chạy truy vấn “select * from sys.xml_schema_types” trên máy chủ).

Hãy xem cách máy chủ sẽ lưu một cấu trúc phức tạp hơn tương tự như cấu trúc trong Ví dụ 1 và được mô tả bằng Bộ sưu tập lược đồ XML.

Ví dụ 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>');

Máy chủ sẽ lưu insert dữ liệu như sau:

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

Hãy thử thêm một liên kết giản đồ vào phần chèn.

Ví dụ 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

Như bạn có thể thấy, máy chủ đã cẩn thận lưu không gian tên dưới dạng thuộc tính và sử dụng gần một nửa không gian cho việc này mặc dù thực tế là không gian tên không thực sự phục vụ bất kỳ mục đích hữu ích nào ở đây - dữ liệu đã được lưu giống như cách nó sẽ diễn ra. được lưu mà không có vùng tên.

Kết luận

Từ những điều trên, có vẻ như bạn có thể giảm kích thước của cơ sở dữ liệu bằng cách lưu trữ một số kiểu dữ liệu (ví dụ:float) dưới dạng giá trị đã nhập vì 4 byte yêu cầu dung lượng ít hơn đáng kể so với cùng một giá trị được lưu dưới dạng chuỗi Unicode. Tuy nhiên, bạn nên nhớ rằng 7-18 byte bổ sung được sử dụng cho mỗi giá trị để mô tả kiểu của nó và di chuyển nó đến vị trí cần thiết.

Phụ lục

Mối tương quan của các kiểu XML, kiểu cơ sở và kiểu dữ liệu mà máy chủ sử dụng để lưu trữ các giá trị đã nhập.

Loại XML Loại cơ sở Được lưu trữ dưới dạng loại Kích thước tính bằng byte
anyType chuỗi 2 * ký tự
anySimpleType anyType chuỗi
chuỗi anySimpleType chuỗi
boolean anySimpleType boolean 1
float anySimpleType float 4
gấp đôi anySimpleType gấp đôi 8
thập phân anySimpleType SqlDecimal 20
thời lượng anySimpleType chuỗi
dateTime anySimpleType * 1
thời gian anySimpleType * 1
ngày anySimpleType * 1
gYearMonth anySimpleType chuỗi
gYear anySimpleType chuỗi
gMonthDay anySimpleType chuỗi
gDay anySimpleType chuỗi
gMonth anySimpleType chuỗi
hexBinary anySimpleType mảng byte
base64Binary anySimpleType mảng byte
anyURI anySimpleType chuỗi
QName anySimpleType chuỗi
normalizedString chuỗi chuỗi
mã thông báo chuỗi chuỗi
ngôn ngữ chuỗi chuỗi
Tên chuỗi chuỗi
NCName chuỗi chuỗi
ENTITY chuỗi chuỗi
NMTOKEN chuỗi chuỗi
số nguyên thập phân SqlDecimal 20
nonPositiveInteger số nguyên SqlDecimal 20
negativeInteger nonPositiveInteger SqlDecimal 20
dài số nguyên SqlDecimal 20
int dài SqlDecimal 20
ngắn int SqlDecimal 20
byte ngắn SqlDecimal 20
nonNegativeInteger số nguyên SqlDecimal 20
unsignedLong nonNegativeInteger SqlDecimal 20
unsignedInt unsignedLong SqlDecimal 20
unsignedShort unsignedInt SqlDecimal 20
unsignedByte unsignedShort SqlDecimal 20
positiveInteger nonNegativeInteger SqlDecimal 20
ký tự chuỗi chuỗi
nchar chuỗi chuỗi
varchar chuỗi chuỗi
nvarchar chuỗi chuỗi
văn bản chuỗi chuỗi
ntext chuỗi chuỗi
varbinary base64Binary mảng byte
nhị phân base64Binary mảng byte
hình ảnh base64Binary mảng byte
dấu thời gian base64Binary mảng byte
timestampNumeric dài SqlDecimal 20
số thập phân SqlDecimal 20
bigint dài SqlDecimal 20
smallint ngắn SqlDecimal 20
tinyint unsignedByte SqlDecimal 20
bit boolean boolean 1
thực float float 4
ngày giờ dateTime * 1
smalldatetime dateTime * 1
tiền thập phân SqlDecimal
smallmoney thập phân SqlDecimal
uniqueidentifier thập phân chuỗi
datetime2 dateTime * 1
datetimeoffset dateTime * 1
phân cấp chuỗi chuỗi
dbobject anyURI chuỗi

* 1 - thông tin dữ liệu / thời gian. Loại cụ thể được xác định bởi giá trị.

Giá trị Được lưu trữ dưới dạng loại Kích thước tính bằng byte
DateOffset Ngày (số ngày) 3
DateOffset (2019-09-16 + 02:00) DateTimeOffset 11
DateTime DateTime 7-9 phụ thuộc vào độ chính xác
DateTimeOffset DateTimeOffset 9
Thời gian DateTime 7-9 phụ thuộc vào độ chính xác
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. TSQL - Thêm cột vào tất cả các bảng trong cơ sở dữ liệu [Ví dụ về con trỏ]

  2. Cách mã hóa một dạng xem trong SQL Server

  3. Giới thiệu về các hàm có giá trị bảng nội tuyến (ITVF) trong SQL Server

  4. Làm cách nào để di chuyển một bảng vào một lược đồ trong T-SQL

  5. Dấu thời gian trong T-Sql trong C # có nghĩa là gì?