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 ...
随机推荐
- FB面经 Prepare: Make Parentheses valid
给一组括号,remove最少的括号使得它valid 从左从右各scan一次 package fb; public class removeParen { public static String fi ...
- C#学习笔记(2)
1.获取当前可用串口端口号 using System.IO.Ports; string[] portNames = SerialPort.GetPortNames(); 2.TextBox换行.设置光 ...
- 计算机网络网络层的IP地址划分及子码
现在在网络层,即就是TCP/IP协议里的网际互联层,最流行IP协议的就是IPV4.其中IP地址的格式是由32位二进制数字表示的,通常为了人们阅读习惯,将其转换成点分十进制来表示,如:192.168.1 ...
- cocos2dx在win10系统上的VS2017运行时报错:丢失MSVCR110.dll
如题,运行环境为cocos2dx 3.14.1,win10系统,VS2017. 编译cocos2dx的cocos2d-x-3.14.1/build/cocos2d-Win32.sln已通过,不过运行时 ...
- Python在终端通过pip安装好包以后,在Pycharm中依然无法使用的解决办法
在终端通过pip装好包以后,在pycharm中导入包时,依然会报错.新手不知道具体原因是什么,我把我的解决过程发出来. pip install 解决方案一: 在Pycharm中,依次打开File--- ...
- typeHandler
package com.cainiao.aeye.chdir.manager.tddl.Handler; import com.cainiao.aeye.chdir.core.enums.AudioF ...
- CSS——img自适应div大小
代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...
- LInux命令英文全称
Linux命令英文全称 su = Swith user 切换用户,切换到root用户cat = Concatenate 串联uname = Unix name 系统名称df = Disk free ...
- op 和 oo 的区别
本是之前一位前辈留下的问题,因为我不是程序出身,略懂一些代码,后又查了很多人的博客,问了周围搞开发的朋友,得出以下结论: 有人这么形容OP和OO的不同:用面向过程的方法写出来的程序是一份蛋炒饭,而用面 ...
- mongo 修改器
[$inc] 作用:修改器$inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作. Example: db.b.update({"uid" : "2 ...