sql >> データベース >  >> RDS >> Sqlserver

SQLServerへのXMLデータの保存

    dbForgeトランザクションログのリリースに取り組んでいるとき、他のタスクの中でも、私たちのチームは、型指定されたXMLデータを適切に保存する方法をパズルで解く必要がありました。

    まず、SQLServerは入力された形式でXMLを保存しないことに注意してください。 XML文字列は解析され、タグに分割されるため、圧縮形式で保存されます。サーバーが不要と見なす記述要素は破棄されます。

    列のデータ型が単純なXMLとして指定されている場合、サーバーはこのデータをUnicode文字列として格納することにも注意してください。
    例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>');

    サーバーは挿入を保存します 次のようなデータ:

    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
    

    次の例では、列のデータ型はXMLスキーマコレクションを介して入力されたものとして指定されています。

    例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
    

    この特定のケースでは、サーバーは挿入を保存します 次のようなデータ:

    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
    

    このようにして、サーバーは保存されたデータをこの記事の補遺で指定されたタイプに変換します(サーバーで「select * fromsys.xml_schema_types」クエリを実行すると、すべてのデータタイプのリストを確認できます)。

    サーバーが例1にあるような、XMLスキーマコレクションで説明されているようなより複雑な構造をどのように保存するかを見てみましょう。

    例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>');
    

    サーバーは挿入を保存します 次のようなデータ:

    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
    

    挿入物にスキーマリンクを追加してみましょう。

    例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
    

    ご覧のとおり、サーバーは名前空間を属性として慎重に保存し、名前空間がここでは実際には何の役にも立たないにもかかわらず、このためにほぼ半分のスペースを使用しました。データは同じように保存されました。名前空間なしで保存されます。

    結論

    上記のことから、4バイトはUnicode文字列として保存された同じ値よりも大幅に少ないストレージを必要とするため、一部のデータ型(floatなど)を型付き値として保存することでデータベースのサイズを縮小できるように思われるかもしれません。ただし、タイプを記述して必要な位置に移動するために、各値に7〜18バイトが追加で使用されることに注意してください。

    補遺

    サーバーが型付きの値を格納するために使用するXMLタイプ、基本タイプ、およびデータ型の相関関係。

    XMLタイプ 基本タイプ タイプとして保存 バイト単位のサイズ
    anyType 文字列 2*文字
    anySimpleType anyType 文字列
    文字列 anySimpleType 文字列
    ブール値 anySimpleType ブール値 1
    フロート anySimpleType フロート 4
    ダブル anySimpleType ダブル 8
    10進数 anySimpleType SqlDecimal 20
    期間 anySimpleType 文字列
    dateTime anySimpleType * 1
    時間 anySimpleType * 1
    日付 anySimpleType * 1
    gYearMonth anySimpleType 文字列
    gYear anySimpleType 文字列
    gMonthDay anySimpleType 文字列
    gDay anySimpleType 文字列
    gMonth anySimpleType 文字列
    hexBinary anySimpleType バイトの配列
    base64Binary anySimpleType バイトの配列
    anyURI anySimpleType 文字列
    QName anySimpleType 文字列
    normalizedString 文字列 文字列
    トークン 文字列 文字列
    言語 文字列 文字列
    名前 文字列 文字列
    NCName 文字列 文字列
    エンティティ 文字列 文字列
    NMTOKEN 文字列 文字列
    整数 10進数 SqlDecimal 20
    nonPositiveInteger 整数 SqlDecimal 20
    negativeInteger nonPositiveInteger SqlDecimal 20
    長い 整数 SqlDecimal 20
    int 長い SqlDecimal 20
    短い int SqlDecimal 20
    バイト 短い SqlDecimal 20
    nonNegativeInteger 整数 SqlDecimal 20
    unsignedLong nonNegativeInteger SqlDecimal 20
    unsignedInt unsignedLong SqlDecimal 20
    unsignedShort unsignedInt SqlDecimal 20
    unsignedByte unsignedShort SqlDecimal 20
    positiveInteger nonNegativeInteger SqlDecimal 20
    char 文字列 文字列
    nchar 文字列 文字列
    varchar 文字列 文字列
    nvarchar 文字列 文字列
    テキスト 文字列 文字列
    ntext 文字列 文字列
    varbinary base64Binary バイトの配列
    バイナリ base64Binary バイトの配列
    画像 base64Binary バイトの配列
    タイムスタンプ base64Binary バイトの配列
    timestampNumeric 長い SqlDecimal 20
    数値 10進数 SqlDecimal 20
    bigint 長い SqlDecimal 20
    smallint 短い SqlDecimal 20
    tinyint unsignedByte SqlDecimal 20
    ビット ブール値 ブール値 1
    本物 フロート フロート 4
    datetime dateTime * 1
    smalldatetime dateTime * 1
    お金 10進数 SqlDecimal
    smallmoney 10進数 SqlDecimal
    一意の識別子 10進数 文字列
    datetime2 dateTime * 1
    datetimeoffset dateTime * 1
    hierarchyid 文字列 文字列
    dbobject anyURI 文字列

    * 1 –データ/時間情報。特定のタイプは値によって定義されます。

    タイプとして保存 バイト単位のサイズ
    DateOffset 日付(日数) 3
    DateOffset(2019-09-16 + 02:00) DateTimeOffset 11
    DateTime DateTime 7-9は精度に依存します
    DateTimeOffset DateTimeOffset 9
    時間 DateTime 7-9は精度に依存します
    TimeOffset(01:23:45Z) DateTimeOffset 9

    1. MariaDBでのLN()のしくみ

    2. SQLで文字列をトリミングする方法

    3. ORA-00933内部結合およびasとの混同

    4. INSERT ... ON DUPLICATE KEY(何もしない)