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 ...
随机推荐
- Pycharm中Python3连接Oracle
一.环境配置:系统:win7.10 (64位)软件:1.Python3.7.2 (64位)2.instantclient-basic-windows.x64-11.2.0.4.0.zip(64位) - ...
- 安利一个vps,7美元/年。
黑色星期五.给大家安利一个vps,7美元/年.配置如下:2 个虚拟化 CPU 2 GB (2048 MB) 专属内存 50 GB RAID-10 受保护硬盘存储 3000 GB (3TB) 月流量 1 ...
- 重谈react优势——react技术栈回顾
react刚刚推出的时候,讲react优势搜索结果是几十页. 现在,react已经慢慢退火,该用用react技术栈的已经使用上,填过多少坑,加过多少班,血泪控诉也不下千文. 今天,再谈一遍react优 ...
- ls file less
ls-a 列出所有文件,包含隐藏文件-l 以长格式显示结果-F 在所列出的文件后面显示其格式-r 按照文件名降序展示-t 按照时间列出-S 按照文件大小排序 file 文件名:展示文件的类型简单描述 ...
- 关于MySQL中的自联结的通俗理解
关于MySQL中的自联结的通俗理解 前言:最近在通过SQL必知必会这本书学习MySQL的基本使用,在学习中也或多或少遇到了点问题,我也正好分享给大家,我的这篇博客用到的所有表格的代码都是来自SQL必知 ...
- 用Nuget部署程序包
用Nuget部署程序包 Nuget是.NET程序包管理工具(类似linux下的npm等),程序员可直接用简单的命令行(或VS)下载包.好处: (1)避免类库版本不一致带来的问题.GitHub是管理源代 ...
- log4j2教程【RollingFileAppender】
说明 rollover 表示的是当日志文件大小满足指定大小后,就生成一个新的文件的过程. RollingFileAppender RollingFileAppender是一个OutputStreamA ...
- Machine Learning 第三周
ML week3 逻辑回归 Logistic Function h_\theta(x)=g(\theta^Tx) g(t)=\frac{1}{1+e^{-z}} 当t大于0, 即下面公式成立时,y=1 ...
- laravel composer
composer config -g repo.packagist composer https://packagist.phpcomposer.com 改安装包的全局镜像网址
- flask实战-个人博客-虚拟环境、项目结构
个人博客 博客是典型的CMS(Content Management system,内容管理系统),通常由两部分组成:一部分是博客前台,用来展示开放给所有用户的博客内容:另一部分是博客后台,这部分内容仅 ...