BLOB数据类型(邀测中)

BLOB(Binary Large Object)即二进制大对象,通常用于存储较大的二进制文件,例如音频、视频、图像等文件。Lindorm宽表SQL支持BLOB数据类型,使用时可以直接将Lindorm宽表中的一个非主键列的数据类型定义为BLOB类型。本文介绍如何使用Lindorm宽表的BLOB数据类型。

适用引擎

BLOB数据类型仅适用于宽表引擎。

前提条件

重要

BLOB数据类型目前处于邀测阶段,如有使用需求,请联系Lindorm技术支持(钉钉号:s0s3eg3)申请使用名额。

注意事项

Lindorm宽表的主键列不支持BLOB数据类型。

DDL

您可以在创建表或修改表时,指定相关列的数据类型为BLOB。

  • 执行以下语句,创建表tb并指定p1为主键列且类型为INT,c1列和c2列为非主键列,且类型分别为VARCHAR和BLOB。

    CREATE TABLE tb (p1 INT, c1 VARCHAR, c2 BLOB, PRIMARY KEY(p1));
    说明
    • 如果表名中需要包含下划线(_)等特殊字符,请在建表时指定BLOB_BUCKET_NAME属性。BLOB_BUCKET_NAME属性的详细介绍,请参见表属性(table_options)

    • 建表语法,请参见CREATE TABLE

  • 执行以下语句,在表中新增c3列并指定c3列为BLOB类型。

    ALTER TABLE tb ADD COLUMN c3 BLOB;
    重要
    • 增加列的语法,请参见ALTER TABLE

    • 宽表引擎2.6.4之前的版本,如果在建表时未设置BLOB列,那么通过ALTER TABLE ADD COLUMN添加的BLOB列将出现数据读写问题。建议您将宽表引擎升级至2.6.4及以上版本。如何查看或升级当前版本,请参见宽表引擎版本说明升级小版本

    • 宽表引擎2.6.4及以上版本,通过ALTER TABLE ADD COLUMN添加BLOB列时,系统默认以数据库名和表名来拼接BLOB_BUCKET_NAME。如果拼接后的BLOB_BUCKET_NAME不满足BUCKET命名规则,则该语句将报错此时您可以显式自定义一个符合命名规则的BLOB_BUCKET_NAME,例如ALTER TABLE tb_name SET 'BLOB_BUCKET_NAME'='my-bucket-name';。BUCKET命名规则请参见表属性(table_options)

    • 如果原表已设置BLOB_BUCKET_NAME属性,请不要修改。您可以在集群管理系统的概览页面,单击目标数据库下的目标表名。在当前详情表格区域,单击查看表属性,查看原表是否设置了BLOB_BUCKET_NAME属性。如何进入集群管理系统,请参见登录集群管理系统

DML

说明

目前BLOB数据类型的DML操作仅支持Lindorm JDBC Driver方式。如何通过Lindorm JDBC Driver连接宽表引擎,请参见使用Java语言JDBC接口的应用开发

数据写入

BLOB列可通过PreparedStatement#setBlob(int parameterIndex, InputStream inputStream, long length)方式绑定参数并写入数据。inputStream参数表示传入InputStream对象,length为InputStream对象中数据的大小。示例代码如下:

String upsert = "upsert into " + tableName + "(p1,c1,c2) values(?, ?, ?)";
int len = 20*1024*1024 + 3;
byte[] v = new byte[len];
try (PreparedStatement pStmt = conn.prepareStatement(upsert)) {
pStmt.setInt(1, 1);
pStmt.setString(2, "123");
pStmt.setBlob(3, new ByteArrayInputStream(v), len); //流写BLOB数据
pStmt.executeUpdate();
}

数据读取

Lindorm支持以下两种方式读取BLOB列的数据:

  • 方式一:一次性读取一行数据中整个BLOB列的全部内容,并保存至一个字节数组中。

    //直接读取整个BLOB列的完整内容
    ResultSet resultSet = stmt.executeQuery("select * from " + tableName + " where p1 = 1" );
    byte[] readBytes2 = resultSet.getBytes(3);
  • 方式二:获取BLOB列中的InputStream对象进行读取。

    说明
    • 仅Lindorm JDBC Driver为2.1.3及以上版本时,可以通过该方式读取数据。

    • 如果需要在后续业务逻辑中进行流式处理,请选择该方式。

    //获取BLOB列对应的InputStream对象进行读取
    ResultSet resultSet = stmt.executeQuery("select * from " + tableName + " where p1 = 1" );
    Blob blob = resultSet.getBlob(3);
    InputStream inputStream = blob.getBinaryStream();
    ....//应用从InputStream对象中获取数据,进行流式处理
    blob.free();    //使用完成后需要释放

函数说明

目前BLOB数据类型支持以下函数,可用于SQL操作。

  • blob_sizeof:获取一行数据中指定BLOB列的大小。输入值类型为BLOB,返回值类型为INTEGER。

    示例如下:

    使用blob_sizeof函数获取数据类型为BLOB,名为c2的列的大小。

    SELECT blob_sizeof(c2) FROM testBlob WHERE p1 = 1;
  • blob_url:获取一行数据中指定BLOB列的下载地址。输入值类型为BLOB,返回值类型为VARCHAR。

    示例如下:

    使用blob_url函数获取数据类型为BLOB,名为c2的列的下载地址。

    SELECT blob_url(c2) FROM testBlob WHERE p1 = 1;
    说明

    返回结果为HTTP地址,可以通过这个地址下载BLOB列。