LOB -part1-Overview

本文主要是对LOB的一些基本特性的概括和总结,特性主要针对11.2的版本。

Large objects简称LOB,是设计用来存放大数据量的一种数据类型。11.2的文档中,基于数据库的配置情况,LOB可以存放8 terabytes到128 terabytes大小的数据。

当前世界上数据格式主要有以下4种:
简单结构类型的数据,可以基于商业规则被设计组织成简单的表;
复杂结构类型的数据,这种类型的数据适合object-relational类型的特性,比如collection,reference或者用户定义类型;
半结构类型数据,这种类型的数据是具有逻辑结构。例如被外部sevice或应用访问的XML document就是这种类型的数据,oracle使用XML DB、高级队列和Messages来提供支持这种类型的数据。
非结构化类型数据,这种类型的数据不能被打散成更小的逻辑结构,比如图片就是非结构化数据的一种,是以二进制文件的方式存储的,无法切分成更小的逻辑结构。

那么Oracle的LOB类型使用上面的哪种或者哪几种类型的数据呢?Oracle的LOB适用于上述的半结构化数据和非结构化数据,LOB的特性允许我们将这些类型的数据存储在数据库中或者可以被数据库访问的操作系统的文件系统中。

对于半结构化数据,Oracle的LOB如何使用呢?与application关联的半结构化数据一般是使用大量的字符数据,这种情况下Character Large Object (CLOB) and National Character Large Object (NCLOB)比较适合存储和操作这种类型的数据,Binary File objects (BFILE)也可以存储这种字符类型,我们可以使用BFILES来从操作系统的文件系统中加载只读数据到CLOB或者NCLOB来提供给application。

同理,对于非结构数据呢?非结构化数据比如text文件、图像文件,video文件,声音波形文件都是size比较大的文件类型。适用这种非结构类型的包括BLOB和BFILE数据类型。

LOB的类型包括internal LOBs、External LOBs(BFILE)。
Internal LOBs包括BLOB、CLOB和NCLOB,这些类型是存储在数据库的表空间中,并且进行了空间的优化和访问效率的优化。Internal LOBs(数据库中的LOBs)可以是永久的(persitent)或者是临时的(temporary)。Persistent lob是存在表的行中的LOB instance。临时lob instance是当你在local application的处理范围内实例化lob的时候创建的,当插入instance到table row的时候临时instance就转变成永久的instance,永久的LOBs遵守数据库的ACID,可以进行介质恢复、事务提交回退等。External LOBs是数据存储在操作系统的文件系统上,是位于数据库表空间以外,数据库使用BFILE访问这些数据,BFILE是唯一的外部LOB数据类型。BFILE是只读的,你不能在应用系统中对BFILE进行写操作,数据库使用只读的字节流来访问BFILEs数据。External LOBs的完整性和持久性需要由操作系统提供的文件系统来保证。

比较重要的是LOB的组成,LOB instance包含一个LOB locator和一个LOB value。Lob locator是lob value的一个引用,lob value是物理存储在LOB中的。当在操作LOB的时候比如将LOB作为一个参数传递的时候实际上传递的是lob locator。

Large object包含BLOB,CLOB,NCLOB和BFILE。

BLOB:Binary Large Object,Stores any kind of data in binary format. Typically used for multimedia data such as images, audio, and video.
CLOB:Character Large Object,Stores string data in the database character set format. Used for large strings or documents that use the database character set exclusively. Characters in the database character set are in a fixed width format.
NCLOB:National Character Set Large Object Stores string data in National Character Set format. Used for large strings or documents in the National Character Set. Supports characters of varying width format.
BFILE:External Binary File A binary file stored outside of the database in the host operating system file system, but accessible from database tables. BFILEs can be accessed from your application on a read-only basis. Use BFILEs to store static data, such as image data, that is not manipulated in applications.Any kind of data, that is, any operating system file, can be stored in a BFILE. For example, you can store character data in a BFILE and then load the BFILE data into a CLOB specifying the character set upon loading.

LOB列的状态

LOB列的一个cell的可以包含3种状态:
NULL:table cell创建了,但是cell中没有locator和value;
Empty:cell中的lob instance具有locator但是没有value,lob的长度为0;
Populated:cell中的instance具有locator和value。

LOB value的访问

LOB API提供了方法可以显式的打开和关闭LOB instance,包括BLOB/CLOB/NCLOB或BFILE。Oracle提供了2种方式来供我们使用来访问和修改LOB value。
一种是使用DATA接口,一种是使用lob locator。

LOB column的初始化

在将lob instance传递给LOB API的时候,这个instance必须是包含locator的,你可以通过select查询一个空的LOB,但是你却不能传递null lob instance(没有locator)给DBMS_LOB.READ过程。
那么如何初始化一个persistent LOB列呢?在使用PLSQL、OCI、OCCI/PROC、ProCOBOL/VB/OLEDB等程序接口写数据到persistent LOB之前,LOB列(属性)必须是非空的,也就是要包含locator。为了实现这个要求,我们可以在一个INSERT或者UPDATE语句中来完成初始化一个persistent LOB为empty,方法是使用EMPTY_BLOB和EMPTY_CLOB分别对应BLOB和CLOB(NCLOB)。

例如表
SQL> @desc pm.print_media
           Name                            Null?    Type
           ------------------------------- -------- ----------------------------
    1      PRODUCT_ID                      NOT NULL NUMBER(6)
    2      AD_ID                           NOT NULL NUMBER(6)
    3      AD_COMPOSITE                             BLOB
    4      AD_SOURCETEXT                            CLOB
    5      AD_FINALTEXT                             CLOB
    6      AD_FLTEXTN                               NCLOB
    7      AD_TEXTDOCS_NTAB                         PM.TEXTDOC_TAB
    8      AD_PHOTO                                 BLOB
    9      AD_GRAPHIC                               BINARY FILE LOB
   10      AD_HEADER                                PM.ADHEADER_TYP


CREATE OR REPLACE DIRECTORY my_directory_object AS 'oracle/work/tklocal';
INSERT INTO print_media VALUES (1726, 1, EMPTY_BLOB(), 
    'my Oracle', EMPTY_CLOB(), EMPTY_CLOB(),
    NULL, NULL, BFILENAME('my_directory_object', 'my_picture'), NULL);

上述的SQL语句将完成
AD_SOURCETEXT被初始化为my Oracle;
ad_composite, ad_finaltext, and ad_fltextn为empty value;
ad_photo为NULL;
ad_graphic to point to the file my_picture located under the logical directory my_directory_object。

对于BFILE,BFILE的列或属性必须为non-null,我们可以使用BFILENAME函数来初始化BFILE列指向外部的操作系统文件。

LOB INSTANCE的访问包含3种方式:SQL访问、Data Interface和Locator Interface。

SQL方式
对于LOB列数据类型的支持,Oracle的很多函数都提供了内部的支持,我们可以像操作VARCHAR2列类型一样使用SQL语法来访问LOB列类型。

Data Interface方式
我们可以直接查询LOB然后在OCI和PL/SQL中使用INTO给CHAR或者RAW buffer。
下面是一个PLSQL的例子,访问Oracle example提供的PM schema下面的表。
ad_finaltext为CLOB类型。

SQL> set serveroutput on
SQL>
SQL>
SQL>
SQL> DECLARE
  2    final_ad VARCHAR(32767);
  3  BEGIN
  4    SELECT ad_finaltext
  5      INTO final_ad
  6      FROM pm.print_media
  7     WHERE product_id = 2056
  8       and ad_id = 12001;
  9    DBMS_OUTPUT.PUT_LINE(final_ad);
 10  END;
 11  /
TIGER2 2056 Mousepad
Product Number: 2056   Price:$8  Now $4!
This Tiger2 mousepad meets all known industrial standards. It is easy on the eyes, mouse, and pocket.
- The Tiger2 standard mouse pad comes with the Oracle logo.
- Logo free mousepads are available
- Select from red, black, or white backgrounds.


PL/SQL procedure successfully completed.

Locator Interface
传递LOB locator给LOB APIs,在OCI中,一个LOB locator是映射成一个locator的指针来用于访问LOB value。在OCI中,APIs操作LOB value都是隐式操作,所以不需要去dereference LOB locator。
关于OCI访问的细节请查看LOB locator semantics in OCI

LOB的规则和限制

  1. LOB不能作为PK列;
  2. Remote LOB支持CTAS模式、返回标量的函数、Data Interface方式;
  3. Clusters不能包含LOB;
  4. 只能作为temporary lob的数据结构:VARRAY of any LOB type,VARRAY of any type containing a LOB type,ANYDATA of any LOB type,ANYDATA of any type containing a LOB;
  5. 不能在group by、order by语句中使用LOB列;
  6. 不能在SELECT DISTINCT或者SELECT UNIQUE语句中或者join中指定LOB列,但是可以是object type列的LOB属性;
  7. LOB segment的第一次INITIAL extent必须至少包含3个数据块,对小的extent大小是14个块,8k块大小的话就是112K;
  8. 触发器中UPDATE OF语句不能指定LOB列;
  9. In SQL Loader, A field read from a LOB cannot be used as an argument to a clause.
  10. Session migration is not supported for BFILEs in shared server (multithreaded server) mode.
  11. 在CLOB中大小写不敏感的查询通常情况下不会成功。
此条目发表在LOB分类目录。将固定链接加入收藏夹。

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s