Oracle Xmltype类型浅析

 

Oracle中,我们对于文件等复杂而且大体积的数据对象通常选择使用lob类型系列变量。Lob类型对于文件等复杂对象是一种不错的保存选择。为了实现对XML数据文件的保存支持和操作支持,Oracle提供了数据类型xmltype作为XML数据的特殊存储类型。Xmltype提供了适合的保存、检索和操作的支持,本篇就简单介绍一下xmltype的一些特性。

 

 

1xml格式使用

 

定义一个xmltype数据列表同一般的数据列没有过多的差异。我们选择Oracle 10gR2作为实验环境。

 

 

SQL> select * from v$version;

 

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE     10.2.0.1.0       Production

 

TNS for 32-bit Windows: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 – Production

 

 

我们可以将数据列定义为xmltype上,xmltypeOracle 10g中是作为专门的保存XML格式。

 

 

SQL> create table t (id number, cl xmltype);

Table created

 

SQL> desc t;

Name Type    Nullable Default Comments

---- ------- -------- ------- --------

ID   NUMBER  Y                        

CL   XMLTYPE Y              

 

 

数据字段定义为xmltype之后,在进行数据保存过程中都会进行格式检查,当不合乎XML通用规则数据尝试保存入系统时,Oracle都会报错。

 

 

SQL> insert into t values (1,'ddd');

insert into t values (1,'ddd')

 

ORA-31011: XML 语法分析失败

ORA-19202: XML 处理

LPX-00210: 预期为 '而不是 'd'

Error at line 1

 时出错

 

SQL> insert into t values (1,'ddd');

1 row inserted

 

SQL> commit;

Commit complete

 

SQL> select * from t;

        ID CL

---------- --------------------------------------------------------------------------------

         1 ddd

 

 

可见,对于不合乎基本XML格式的数据,Oracle是不允许进行保存的。

 

2XMLTYPELOB

 

Xmltype字段的是可以容纳入XML格式文件,那么该类型字段的本质是什么呢?

 

 

SQL> select segment_name, segment_type, tablespace_name from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE       TABLESPACE_NAME

------------------------------ ------------------ ------------------------------

SYS_LOB0000056127C00003$$      LOBSEGMENT         USERS

T                              TABLE                USERS

SYS_IL0000056127C00003$$       LOBINDEX           USERS

 

9 rows selected

 

 

SQL> select table_name, column_name,SEGMENT_NAME, TABLESPACE_NAME, INDEX_NAME from user_lobs;

 

TABLE_NAME COLUMN_NAME          SEGMENT_NAME                   TABLESPACE INDEX_NAME

---------- -------------------- ------------------------------ ---------- ------------------------------

T          SYS_NC00003$         SYS_LOB0000056127C00003$$      USERS      SYS_IL0000056127C00003$$

 

 

我们发现,数据表T中多出了一个Lob数据段和Lob索引段,这个特性与LOB类型数据特性相同。值得关注的是在user_lobs中,显示的column_name是一个未知的名称“SYS_NC00003$”。那么我们就继续从这个线索入手。

 

我们需要检查一下基础元数据表信息。

 

 

SQL> select object_id, data_object_id from dba_objects where wner='SCOTT' and object_name='T';

 

 OBJECT_ID DATA_OBJECT_ID

---------- --------------

     56136          56139

 

SQL> select col#, segcol#, segcollength, name, type#,charsetform. from col$ where obj#=56136;

 

      COL#    SEGCOL# SEGCOLLENGTH NAME                      TYPE# CHARSETFORM

---------- ---------- ------------ -------------------- ---------- -----------

         1          1           22 ID                            2           0

         2          0         2000 CL                           58           0

         2          2         4000 SYS_NC00003$                112           1

 

 

SYS_NC00003$列,我们根据charsetform字段的取值,可以确定具体类型。

 

 

//片段来自dba_tab_cols视图定义;

 

112, decode(c.charsetform, 2, 'NCLOB', 'CLOB'),

 

 

由此,我们可以基本猜想出xmltype的结构类型。作为xmltypeOracle会在数据表上建立一个clob类型的系统列,用于协助保存数据。

 

 

3、数据表定义

 

我们研究lob类型,在定义数据表的时候是有专门的lob(xxx)子句用于指定lob的一些存储信息。而在xmltype中,也存在这样的接口方式吗?我们使用dbms_metadata包抽取出数据表的元数据信息。

 

 

CREATE TABLE "SCOTT"."T"

   ( "ID" NUMBER,

       "CL" "SCOTT"."XMLTYPE"

   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

  TABLESPACE "USERS"

 XMLTYPE COLUMN "CL" STORE AS CLOB (

  TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10

  NOCACHE LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)) ;

 

 

注意,此处是使用xmltype column xx store as clob子句进行定义。后面的关于storage的内容都是针对虚拟Lob列段对象而言的。

 

这里,我们反过来想,如果我们使用xmltype column子句,是不是也可以在定义数据表的过程就将Lob与数据表存储分开,放置在不同的表空间里。

 

4、创建xmltype表到不同表空间

 

借助xmltype column子句,我们可以实现在数据表建表阶段,就将Lob相关段和数据表分开。

 

 

SQL> create table t (id number, cl xmltype) tablespace users  XMLTYPE COLUMN "CL" STORE AS CLOB (tablespace example);

Table created

 

 

SQL> select segment_name, segment_type, tablespace_name from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE       TABLESPACE

------------------------------ ------------------ ----------

T                              TABLE              USERS

 

SYS_IL0000056132C00003$$       LOBINDEX           EXAMPLE

SYS_LOB0000056132C00003$$      LOBSEGMENT         EXAMPLE

 

9 rows selected

 

SQL> select table_name, column_name,SEGMENT_NAME, TABLESPACE_NAME, INDEX_NAME from user_lobs;

 

TABLE_NAME COLUMN_NAME          SEGMENT_NAME                   TABLESPACE INDEX_NAME

---------- -------------------- ------------------------------ ---------- ------------------------------

T          SYS_NC00003$         SYS_LOB0000056132C00003$$      EXAMPLE    SYS_IL0000056132C00003$$

 

 

如我们所希望的,数据表和Lob段(数据段和索引段)分别放置在了不同表空间里。

 

5、数据表Move操作

 

数据表move操作可以实现将数据表段和相关段对象转移到其他表空间或者收缩的作用。对包含xmltype列的数据表,move操作效果如何呢?

 

 

SQL> select segment_name, segment_type, tablespace_name from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE       TABLESPACE

------------------------------ ------------------ ----------

T                              TABLE              USERS

SYS_LOB0000056136C00003$$      LOBSEGMENT         USERS

SYS_IL0000056136C00003$$       LOBINDEX           USERS

 

9 rows selected

 

SQL> alter table t move tablespace example;

Table altered

 

SQL> select segment_name, segment_type, tablespace_name from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE       TABLESPACE

------------------------------ ------------------ ----------

SYS_LOB0000056136C00003$$      LOBSEGMENT         USERS

SYS_IL0000056136C00003$$       LOBINDEX           USERS

T                              TABLE              EXAMPLE

 

9 rows selected

 

 

发现在Oracle 10g下,如果单纯的使用move命令,段效果变化同一般的lob类型是一样的。数据表T移动到了新的表空间位置,而对应的lob段没有变化。同时,还要注意,lob索引的状态保持valid状态。

 

 

SQL> select index_name, index_type, table_name, status from user_indexes where table_owner='SCOTT' and table_name='T';

 

INDEX_NAME                     INDEX_TYPE                  TABLE_NAME STATUS

------------------------------ --------------------------- ---------- --------

SYS_IL0000056136C00003$$       LOB                         T          VALID

 

 

如果我们尝试使用move lob命令会如何呢?

 

//普通调用无效,因为cl不是一个lob类型;

sQL> alter table t move lob(cl) store as xmlseg tablespace example;

 

alter table t move lob(cl) store as xmlseg tablespace example

 

ORA-00904: "CL": 标识符无效

 

//尝试移动隐含列对象;

SQL> alter table t move lob(SYS_NC00003$) store as mt (tablespace example);

Table altered

 

SQL> select segment_name, segment_type, tablespace_name from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE       TABLESPACE_NAME

------------------------------ ------------------ ------------------------------

T                              TABLE               EXAMPLE

SYS_IL0000056136C00003$$       LOBINDEX           EXAMPLE

MT                             LOBSEGMENT         EXAMPLE

 

 

从上面的实验中,我们可以看出:当我们对lob进行move的时候,如果使用数据列(xmltype),数据操作是不支持的。换而使用对隐含列的操作时,可实现对一个已经创建数据表的Lob段进行移动。

 

注意:当我们使用到Oracle 11g的时候,事情有所差异。

 

 

SQL> select * from v$version;

BANNER

--------------------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

PL/SQL Release 11.2.0.1.0 - Production

CORE     11.2.0.1.0       Production

 

TNS for Linux: Version 11.2.0.1.0 - Production

NLSRTL Version 11.2.0.1.0 - Production

 

 

我们在11g上进行试验。

 

 

SQL> create table t (id number, cl xmltype) tablespace system;

Table created

 

SQL> select segment_name, segment_type, tablespace_name from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE       TABLESPACE

------------------------------ ------------------ ----------

T                              TABLE              SYSTEM

SYS_IL0000075364C00003$$       LOBINDEX           SYSTEM

SYS_LOB0000075364C00003$$      LOBSEGMENT         SYSTEM

 

9 rows selected

 

 

此时,我们进行move操作。

 

 

SQL> alter table t move tablespace users;

Table altered

 

SQL> select segment_name, segment_type, tablespace_name from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE       TABLESPACE

------------------------------ ------------------ ----------

T                              TABLE              USERS

SYS_IL0000075364C00003$$       LOBINDEX           USERS

SYS_LOB0000075364C00003$$      LOBSEGMENT         USERS

 

9 rows selected

 

 

可以看到,11g里进行move操作的时候,数据表和XmlType Lob段做到同时移动。

 

那么move是否有如10g特性呢?

 

 

SQL> select object_id, data_object_id, object_name from dba_objects where object_name='T' and wner='SCOTT';

 

 OBJECT_ID DATA_OBJECT_ID OBJECT_NAME

---------- -------------- -------------

     75364          75367 T

 

 

隐藏虚拟列信息如下:

 

SQL> select * from col$ where obj#=75364;

 

      OBJ#       COL#    SEGCOL# SEGCOLLENGTH     OFFSET NAME  TYPE# 

---------- ---------- ---------- ------------ ---------- -------------------- ----------

     75364          1          1           22          0 ID                  2 

     75364          2          0         2000          0 CL                 58  

     75364          2          2         4000          0 SYS_NC00003$      112  

 

 

lob段进行move操作。

 

 

SQL> alter table t move lob(SYS_NC00003$) store as xmlseg (tablespace system);

Table altered

 

SQL> select segment_name, segment_type, tablespace_name from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE                   TABLESPACE_NAME

------------------------------ ------------------------------ ------------------------------

T                              TABLE                          USERS

SYS_IL0000075364C00003$$       LOBINDEX                       SYSTEM

XMLSEG                         LOBSEGMENT                     SYSTEM

 

9 rows selected

 

 

对内部列的操作,成功的在11g中实现将lob段移动到其他表空间里。

 

 

6、结论

 

XMLtype类型是我们保存XML格式文件一种可选的格式类型,提供了各种针对于xml文档的操作和检索。本篇着重分析了Xmltype类型的存储特性和差异。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-708738/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/17203031/viewspace-708738/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值