LOB
一,LOB介绍
1,概念
LOB 是指用来存储大对象的数据类型,一般说LOB只是泛指,具体有BLOB,CLOB,NCLOB,BFILE。
根据你数据库的设置,一个LOB可以存储的最大大小从8TB到128TB不等。
它适用于存储半结构化和非结构化的数据。
在早先的版本里,oracle提供的是LONG类型,虽然目前也一样提供,但oracle建议使用LOB而不是LONG。LOB对比LONG类型的优势在后面说明,可以通过alter table将LONG column转换为LOB类型。
2,LOB的类型
内部 LOBs
所谓的内部指的是数据存储在数据库的表空间里面,支持的类型有BLOB,CLOB,NCLOB。
另外还内部LOB还分为永久的和临时的两种类型。
一个永久的LOB是指存在一个表行里面的LOB实例。而临时的LOB是在你本地应用的范围内,实例化的时候创建的。临时的LOB实例会在你将其插入DB的一个表行后实体化。
实体化的LOB是符合ACID原则的,可以被提交/回滚,以及从事务或介质失败中恢复。
外部LOBs以及BFILE
外部LOBS是存储在操作系统文件中的数据对象,而不是存储在表空间里面。BFILE是唯一的外部LOB数据类型,是只读的,不能在application里面往BFILE里面写数据。
所以以下情况就比较适用BFILE:
应用运行过程中不会变化的二进制数据,比如说图案
数据会被导入到其他类型的LOB中进行操作,也就是BFILE里的数据会被读进BLOB或者说CLOB里面进行操作
流数据,只需要读的多媒体数据
SIZE很大的只读数据,借此避免使用太多的数据库空间
操作系统上的任何存储设备都可以用来保存BFILE数据,比如硬盘驱动,CD-ROMs, PhotoCDs以及DVDs.
BLOB | 二进制 存储任意类型的二进制格式的数据,通常来说用于多媒体数据,比如图像,音频和视频 |
CLOB | 字符型 存储字符串数据,专指数据库的字符集类型,此类字符是固定宽度格式的 |
NCLOB | 国家字符集 存储的也是字符数据,只不过这里的字符是国家字符集内的字符。字符宽度不固定 |
BFILE | 外部二进制文件 存储在操作系统文件系统的二进制文件,可以被DB表所访问。BFILE是只读的,一般用于存储静态数据(或者说你不需要直接变更的) 如果需要变更,可以将BFILE内的数据读进相对应的其他LOB类型中 |
3,Lob Locator
一个LOB实例有一个定位器和一个数值。LOB定位器用于定位LOB数据的物理存储位置,你可以把它当成指针来看。
有时候当你在某个操作里面传递一个LOB,其实传递的只是Locator而已。
这里稍微提一下LOB定位器(Blob, Clob, NCLOB)跟BFILE定位器的区别, 前者是每一行都会存储一个定位器,即便数据一样,在DML过程中也会生成一份Copy。
后者的定位器则是指向操作系统的BFILE文件,不同BFILE的locator是独立的。如果不同的行指向同一个BFILE,则locator是一样的,在insert过程中,只有locator被插入表中。
Note: DB还可以自定义创建一些数据类型以LOB形式存储,比如VARRAY,XMLType
二,LOB存储
1,LOB值可以被初始化为NULL或者Empty,两者的不同的地方的是,NULL是没有locator的,存储的是NULL,这里要注意的是,这里是初始化的时候如果这么设置才会没有locator,后续的变化还是会生成locator的。
Empty则是空值,会有一个locator, 只不过LOB的长度为0.
可以通过以下sql判断是否有null值
SELECT COUNT (*) FROM print_media WHERE ad_graphic IS NULL;
NULL值的LOB无法直接通过OCI或者DBMS_LOB来进行操作,必须先将其更新为非NULL值或者Empty。 因为这些功能/函数,是和locator进行交互的。
通过以下方式设置为Empty:
INSERT INTO a_table VALUES (EMPTY_BLOB());
总的来说,初始化的时候,用以下方式将还未存放数据的LOBs设置为NULL或者Empty:
INSERT INTO print_media VALUES (1001, EMPTY_CLOB(), EMPTY_CLOB(), NULL, EMPTY_BLOB(), EMPTY_BLOB(), NULL, NULL, NULL, NULL);
BFILE可以通过BFILENAME()来设置NULL或者文件名字
2,LOBs和LONG的对比
LOB Data Type | LONG and LONG RAW Data Type |
---|---|
You can store multiple LOBs in a single row |
You can store only one |
|
This is not possible with either a |
Only the LOB locator is stored in the table column; For inline LOBs, the database will store LOBs that are less than approximately 4000 bytes of data in the table column. |
In the case of a |
When you access a LOB column, you can choose to fetch the locator or the data. |
When you access a |
A LOB can be up to 128 terabytes or more in size depending on your block size. |
A |
There is greater flexibility in manipulating data in a random, piece-wise manner with LOBs. LOBs can be accessed at random offsets. |
Less flexibility in manipulating data in a random, piece-wise manner with |
You can replicate LOBs in both local and distributed environments. |
Replication in both local and distributed environments is not possible with a |
3,LOB Value的存储位置
根据创建表时指定的列参数,以及LOB的大小,实际的LOB Value的存储位置分为行内存储和行外存储。
LOB值存储在行外的情况有:
a) 创建表的时候设置了DISABLE
STORAGE
IN
ROW
b) Lob的大小超过了4000 Bytes (4000减去系统控制信息),也就是说不是足量的4000
c) 原本大小超过4000的LOB更新后小于4000,依旧会存储在行外。
LOB值存储在行内的情况有:
a) 当LOB值的大小小于4000Byte的时候,或者显示设置了ENABLE
STORAGE
IN
ROW(或者说没有指定这个参数,也就是默认)
b) 当LOB值为空的时候
Note: 使用默认的LOB存储参数可以获得更好的数据库性能。能够避免大量创建和管理小的LOB数据。如果你存储的LOB数值大多数时候是小的,那么建议使用行内存储。
Locator总是存储在行内
任意一个LOB实例都会有一个locator,不管你的存储参数是什么,也不管你的LOB值是多少
如果一个LOB创建的时候指定了外部存储,并且BASICFILE LOB存有任意数据,那么最少会使用一个CHUNK大小的存储空间,即便LOB的大小小于CHUNK的大小,这里就是存储的额外开销
如果一个LOB的列初始化为Empty, 那么那一行只会存储一个locator,不会有额外的存储被使用
如果LOB的存储参数没有影响BFILE列,那么BFILE的数据总是存储在数据库以外的操作系统文件里面
当你创建LOB对象的时候,你可以为每一个LOB列指定一个表空间,并且设置相应的存储参数,比如说CHUNK size.
4,CHUNK, 它是LOB存储的最小单元。一个CHUNK可以是一个或者多个oracle数据块,它的大小不是固定的,可以在创建表的时候指定。默认情况,CHUNK的大小等于一个表空间块的大小,最大值是32K。
CHUNK的一部分是用来存储系统相关信息(额外开销),剩下的部分才用来存储LOB数据。可以通过DBMS_LOB.GETCHUNKSIZE来获取lob的chunk size. OCI里面,通过OCILobGetChunkSize()获取。
当LOB列创建完成后,CHUNK的大小就不能再改变了,因此在创建之前确定好CHUNK的大小很重要。而对于SECUREFILE LOBs来说,指定的chunk size只是一个建议值,更多是为了向后兼容的目的。
PS:SecureFile跟BASICFile可以看下 https://www.oracle.com/technetwork/database/securefiles-160920-zhs.html
CHUNK的值对行内存储的LOB没有影响。只有当行外存储的时候,不恰当的CHUNK SIZE可能会导致大量空间的浪费。
Data Size | CHUNK Size | Disk Space Used to Store the LOB | Space Utilization (Percent) |
---|---|---|---|
3500 enable storage in row |
irrelevant |
3500 in row |
100 |
3500 disable storage in row |
32 KB |
32 KB |
10 |
3500 disable storage in row |
4 KB |
4 KB |
90 |
33 KB |
32 KB |
64 KB |
51 |
2 GB +10 |
32 KB |
2 GB + 32 KB |
99+ |
关于设置CHUNK的大小,要结合你经常访问的数据大小,假如你经常只访问一个块,那chunk size设置为这个块的大小是最合适的。但是假如你需要访问的LOB数据量都很大,比如2G,那么SIZE设置为32KB的时候,性能是最好的。
5,表空间和LOB索引
对于LOBs来说,最好是指定一个独立的表空间,这样子可以获得最好的性能表现。如果很多不同的LOB访问非常频繁,甚至可以为每一个LOB column单独指定一个表空间,以此来分散设备的争用。
LOB索引是跟LOB存储强相关的内部结构,这意味着用户不能单独删掉或者重建它们。
Note:
LOB index不能被altered
当你建表的时候,如果你为一个非分区表的LOB索引指定了一个表空间,这个指定将会被忽略掉,LOB索引会和LOB数据存储在同一个表空间中。 分区表没有LOB index的语法。
可以在LOB列上创建的索引有:域索引,文本索引,函数索引,扩展索引
Note:
当你移走一个LOB列后,整个表的所有索引都要重建。
不能在LOB列上创建B树索引或者位图索引。
如有错误,望不吝指出
LOB的更多相关文章
- lob结构
lob是什么? 从网上查了好多资料没找到,最后还是同事给我找到了. lob他是这样解释的:LOB专门存储大型对象数据的,类型text.image这些数据类型的数据就是存储在LOB页面 LOB_DATA ...
- jdbc执行预处理,批处理,LOB字段处理,调用存储过程
(1)jdbc执行预处理 PreparedStatment预备语句 eg:String sql="insert into user(id,name,birthday,money) value ...
- varchar2_to_blob,应用向数据库更新LOB字段时的超时问题
将字符串转换为BLOB类型数据,写入服务器. 1,首先利用to_clob函数把varchar2字段转成 clob字段. 2 利用c2b上面函数将clob转成blob. 即: c2b(to_clob( ...
- ORACLE DBA_OBJECTS视图中OBJECT_TYPE为LOB的对象查看
在ORACLE数据库中,DBA_OBJECTS视图中OBJECT_TYPE为LOB的对象是什么东西呢?其实OBJECT_TYPE为LOB就是大对象(LOB),它指那些用来存储大量数据的数据库字段.下面 ...
- ORA-22868: 具有 LOB 的表包含有位于不同表空间的段
由于lob对象引起的表空间无法删除.本来是要删除DMS表空间,但是上面有LOB对象,而且表却是在别的表空间DMS4上.解决的办法就是将这些lob移动到DMS4表空间.下面是解决过程 删除用户时报错: ...
- LOB字段存放在指定表空间 清理CLOB字段及压缩CLOB空间
LOB字段存放在指定表空间 清理CLOB字段及压缩CLOB空间 把LOB字段的SEGMENT 存放在指定表空间.清理CLOB字段及压缩CLOB空间 1.创建LOB字段存放表空间:create ...
- SSH+Oracle10G抛Disabling contextual LOB creation as createClob() m
在使用Oracle10G时候,实体类使用了CLOB字段,结果抛了Disabling contextual LOB creation as createClob() method threw error ...
- java.io.IOException: ORA-22920: 未锁定含有 LOB 值的行
究其原因是因为没有锁定要更新的行记录.将 mysql="select filebody from filelist where filename=?"中的SQL语句加上 ...
- 【LOB】使用USER_LOBS视图获得当前用户包含LOB字段的表
包含LOB类型字段的表往往需要特殊关照,如何快速的获得包含LOB对象的数据库表?使用DBA_LOBS.ALL_LOBS和USER_LOBS视图可以很方便地获得包含BLOB或CLOB字段的表. 简单看一 ...
- How to Release the Temp LOB Space and Avoid Hitting ORA-1652 (文档 ID 802897.1)
APPLIES TO: Oracle Database - Enterprise Edition - Version 8.1.5.0 and laterInformation in this docu ...
随机推荐
- Repeater 实现 OnSelectedIndexChanged
在Repeater中使用DropDownList的方法 在Repeater中使用DropDownList的方法 以下代码并不完整,只记录了关键的方法 aspx代码中 假设这是一个用户管理的系统的模 ...
- libpng warning: iCCP: known incorrect sRGB profile
参考 http://www.cocos2d-x.org/forums/6/topics/49093 解决 I got the following warnings in console when r ...
- 201808_summary
@Consumes @Produces分别表示入参和出参数吗 可以这样讲.但是不是很到位.是限定作用,类似于filterconsumes: 指定处理请求的提交内容类型(Content-Type),例如 ...
- UGUI动态更换精灵图片
//动态更换精灵图片 m_headimage.overrideSprite = Resources.Load("texture/"+info.HeadPortrait,typeof ...
- angular2--Tour of Heroes学习和分析--路由
引入路由模块时的一个报错 No base href set. Please provide a value for the APP_BASE_HREF token or add a base elem ...
- office2007每次打开都要配置文件,怎么取消配置
有时候 Office2007打开文档,每次都提示需要安装.配置,配置完成之后,下次打开又需要配置点击取消就不能打开.非常的烦.ffice2007下载后为什么每次打开总需要置?office2007每次打 ...
- Linux基础命令---iostat显示设备状态
iostat iostat指令用来显示cpu状态,系统IO设备的状态,以及相关磁盘和NFS使用状态.iostat命令通过观察设备相对于其平均传输速率的活动时间来监视系统输入/输出设备负载.iostat ...
- BUAA Summer Practice 2017 #1 字符串专场
https://vjudge.net/contest/262753#overview C - Regular Number HDU - 5972 bitset temp, temp[i]=1表示 此前 ...
- 文件下载的ie11兼容性优化
在 http://www.cnblogs.com/sunshine6/p/8296945.html 中有说关于前后端分离时如何实现文件下载的功能,但是过完年回来,同事告诉我这个方式在ie11上存在不兼 ...
- HTTP 400错误--请求无效
在发送请求后台数据时会报出来HTTP400错误,请求无效,出现这个请求无效报错说明请求没有进入到后台服务里 原因:1.前端提交数据的字段名称或者是字段类型和后台的实体类不一致.导致无法封装 2.前端提 ...