#大对象型
LOB大对象型用于在数据库中存储较大二进制或较大文本的可变长度数据。
YashanDB的LOB类型包括BLOB、CLOB和NCLOB。
# 存储属性
类型 | 字节长度 |
---|---|
BLOB | 行存: 1~4G*DB_BLOCK_SIZE 列存: 无此类型 |
CLOB | 行存: 1~4G*DB_BLOCK_SIZE 列存: 1 ~ 32000Byte |
NCLOB | 行存: 1~4G*DB_BLOCK_SIZE 列存: 无此类型 |
定义格式:
类型 | 格式 | 规则 |
---|---|---|
BLOB | BLOB | 变长二进制串,无需指定size |
CLOB | CLOB | 变长字符串,无需指定size |
NCLOB | NCLOB | 支持UNICODE的变长字符串,无需指定size |
YashanDB对大对象类型的存储包含行内存储和行外存储两种方式:
- 当一行的LOB列的数据小于4000字节时,LOB数据将存储在行内。
- 当超过4000字节时,LOB数据存入单独的大对象数据空间(可为其指定表空间),行内存储的则是指向LOB数据的指针。
Note:
- 数据在存储时会产生一些内部元信息,上述4000字节也包括这部分元数据所占空间。
- 以DB_BLOCK_SIZE = 8K为例,LOB类型数据在行存表中的最大字节长度为
4G*8K=32T
。
# 使用规则
# 使用限制
YashanDB对于LOB型的使用限制如下:
- 不能作为索引列
- 不能修改LOB列的数据类型
- 不能作为分区键
- 不能与其他数据类型进行四则运算和取余运算
此外,列存表对于LOB型还有如下使用限制:
- 不能对含有LOB列的列存表执行UPDATE操作
- 不能以LOB列作为过滤条件对列存表执行DELETE操作
- 开启附加日志(见ALTER TABLE中的add_supplemental_logging_clause)后,不能对列存表执行任何DELETE操作
分布式部署中不支持CLOB作为分布键。
# BLOB
BLOB表示二进制大对象,例如照片、视频、音频等文件,对于这类文件的存储,可采用在数据库中只存储文件地址,读取时通过链接获取文件的方式,也可采用直接将其二进制数据作为BLOB字段存储到数据库表中的方式。
由于BLOB内容为二进制数据,除与RAW类型的隐式数据转换外,该数据类型在SQL中不参与其他任何类型转换及运算,但可以通过DBMS_LOB.COMPARE实现与BLOB/RAW类型数据的比较,该高级包同时提供了对BLOB类型的一些运算方法。
示例
--1.在sales用户下创建含有BLOB字段的customer_img表
CREATE TABLE customer_img (id INT, logo BLOB);
本示例运用YashanDB JDBC驱动客户端程序对customer_img插入一条包含图片的记录,该示例引用到了在YashanDB JDBC驱动使用示例程序中的getConnection方法。
--2.创建java文件
package jdbc0;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.PreparedStatement;
public class Blobexample {
public static void main(String[] args) throws Exception {
//创建数据库连接。
Connection conn = Jdbcexample.getConnection("sales", "sales");
PreparedStatement pst = null;
try {
//生成预处理语句。
pst = conn.prepareStatement("INSERT INTO customer_img VALUES (?,?)");
//添加参数。
pst.setInt(1, 1);
//读取图片文件,转为二进制
FileInputStream in = new FileInputStream("./logo.png");
pst.setBytes(2, trans2Byte(in));
pst.executeUpdate();
System.out.println("insert table customer_img succeed!");
pst.close();
} catch (SQLException e) {
if (pst != null) {
pst.close();
}
e.printStackTrace();
}
}
public static byte[] trans2Byte(FileInputStream in) {
int count = 0;
try {
while (count == 0) {
count = in.available();
}
byte[] blob = new byte[count];
in.read(blob);
return blob;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
--3.在linux下编译并运行
$ javac -d . Blobexample.java
$ java jdbc0.Blobexample
Connection succeed!
insert table customer_img succeed!
--4.查询插入的数据(部分显示)
SELECT * FROM customer_img;
ID PHOTO
------------ ----------------------------------------------------------------
1 89504E470D0A1A0A0000000D49484452000000FA000000440806000000A82C28380000000467414D410000B18F0BFC610500000038655849664D4D002A00000008000187690004000000010000001A000000000002A0020004
# CLOB
CLOB表示可变长度文本,与VARCHAR类型类似,而VARCHAR类型的最大存储规格为32000字节,对于预计可能会存储超过该规格数据的字段,可将其设为CLOB类型。
所有CLOB类型的数据在发送到客户端时会做UTF-8字符集校验, 检验失败将返回错误。
CLOB类型支持大部分字符型函数,也可以在执行数据转换后参与运算,具体见每个函数的描述。
可以通过DBMS_LOB.COMPARE实现CLOB与CLOB/CHAR/VARCHAR类型数据的比较,该高级包同时提供了对CLOB类型的一些运算方法。
示例
--1.在sales用户下创建含有CLOB字段的customer_intro表
CREATE TABLE customer_intro (id INT, intro CLOB);
--2.插入CLOB数据
INSERT INTO customer_intro
VALUES (1, 'It gives me great pleasure to introduce our company.');
COMMIT;
--3.CLOB数据参与字符型运算
SELECT SUBSTRING(intro, 3,5) FROM customer_intro WHERE id = 1;
SUBSTRING(INTRO,3,5)
----------------------------------------------------------------
give
# NCLOB
NCLOB存储UNICODE可变长度数据,与CLOB类型功能类似,最大支持存储1~4G*DB_BLOCK_SIZE数据。
NCLOB类型仅适用于HEAP表。
示例(HEAP表)
--1.创建表NCLOB_TABLE
CREATE TABLE nclob_table (c1 NCLOB);
--2.插入NCLOB数据
INSERT INTO nclob_table
VALUES ('It gives me great pleasure to introduce our company.');
COMMIT;
--3.NCLOB数据转换
SELECT CAST(c1 AS CHAR(90)) FROM nclob_table;
CAST(C1ASCHAR(90))
----------------------------------------------------------------
It gives me great pleasure to introduce our company.