大对象

概念

大对象LOB (Large Object) 的功能是为了突破 SequoiaDB 巨杉数据库的单条记录最大长度为 16MB 的限制,为用户写入和读取更大型记录提供便利。对于文档、图片、音频和视频等非结构化的数据,用户可以使用 LOB 存储。LOB 存放在集合中,每一个 LOB 都需要一个 OID 来唯一标示。LOB 的内容只存放在一个集合中,当集合被删除时,其拥有的 LOB 将自动删除。

存放 LOB 的集合应该满足如下要求:

  • 当集合是普通集合,集合只存在某一个数据组中。此时,LOB 的最大容量为集合能使用的最大文件空间。
  • 当集合是哈希分区集合,LOB 对该哈希分区集合的 ShardingKey 没有要求。一般情况下,用户在创建哈希分区集合来存放 LOB 时,可以使用 “_id” 键作为 ShardingKey。当集合为哈希分区集合时,集合存在一个或者多个数据组中。在这种情况下,LOB 最大的容量由哈希分区集合使用的数据组的数据决定。

存储结构

LOB 以集合为单位进行存储,因此它保持集合空间和集合的逻辑结构。在磁盘的数据存储中,对应的集合空间会增加 2 个文件:

  1. [CollectionSpace].1.lobm
  2. [CollectionSpace].1.lobd

LOBM 文件和 LOBD 文件一一对应,LOBM 为元数据文件,用于 LOB 数据页的分配、查找和管理;LOBD 为 LOB 的数据存储文件,存储真实的数据。

LOBD 在存储数据时,以数据页为最小单位。数据页大小最小为 4KB,最大为 512KB,默认为 256KB。在 LOBD 上存放数据时,若 LOB 总大小小于 1 个数据页的大小,该 LOB 也会独占整个数据页,哪怕该 LOB 大小只有 1 Byte。所以,当存储的 LOB 总大小较小时,用户应该选择适当的数据页大小来存储 LOB 的内容,以减少空间浪费。关于 LOB 的数据页大小的选择,可参考 Sdb.ceateCS() 的 LobPageSize 参数的介绍。

LOBM 和 LOBD 的存储结构如图 1 所示。

LOB 存储文件结构图

功能介绍

目前,LOB 支持以下功能:

  • 顺序读写和随机读写
  • 打开读操作和打开写操作
  • 并发读和并发写

在对 LOB 进行操作时,注意以下情况:

可读可写可删除可并发读可并发写备注
创建LOB××××
打开读LOB×××
打开写LOB××并发写时需要按写入的数据段加锁并 seek 到加锁的数据段后写入数据。
并发锁定的数据段不能重叠。
当某数据段被锁定后,其上面的数据将可被覆盖写入。
关于 LOB 的 seek, lock 和 lockAandSeek 操作,可查看各驱动 LOB 相关 API 的说明。
删除LOB××××

操作说明

下表以在 Sdb Shell 上操作 LOB 来介绍 LOB 相关 API 的使用。

LOB 操作参见说明相关 API
创建SdbCollection.putLob()向集合创建一个 LOB。SdbCollection::openLob() // 以创建的方式打开
SdbLob::write()
SdbLob::close()
读取SdbCollection.getLob()从集合读取某个 LOB 记录。SdbCollection::openLob() // 以只读的方式打开
SdbLob::read()
SdbLob::close()
删除SdbCollection.deleteLob()删除集合某个 LOB 对象。SdbCollection::removeLob()
列表SdbCollection.listLobs()列出集合所有 LOB 对象。SdbCollection::listLobs()

Note:

  • SDB Shell 使用 CPP 驱动连接数据库,上表相关 API 是 CPP LOB API 的情况。其他驱动的 LOB API 拥有类似的接口。详情请参考相关的驱动。
  • 关于 LOB 的更多 API 说明,请参考各驱动 LOB API 的说明。

示例

1.在 Sdb Shell 中将本地视频文件 video_2019_02_26_1.avi 上传至集合 sample.video 中:

  1. > db.sample.video.putLob( '/opt/video_2019_02_26_1.avi' )
  2. 5435e7b69487faa663000897

2.在 Sdb Shell 中查看集合 sample.video 中所有 LOB 及其对应的 OID:

  1. > db.sample.video.listLobs()
  2. {
  3. "Size": 76602,
  4. "Oid": {
  5. "$oid": "5435e7b69487faa663000897"
  6. },
  7. "CreateTime": {
  8. "$timestamp": "2019-02-26-12.51.43.628000"
  9. },
  10. "ModificationTime": {
  11. "$timestamp": "2019-02-26-12.51.45.523000"
  12. },
  13. "Available": true
  14. }

3.在 Sdb Shell 中将集合 sample.video 中的 OID 为 435e7b69487faa663000897 的LOB 下载到本地文件 video_2019_02_26_1_bak.avi 中:

  1. > db.sample.video.getLob( '5435e7b69487faa663000897', '/opt/video_2019_02_26_1_bak.avi' )

4.在 SDB Shell 中将集合 sample.video 中的 OID 为 5435e7b69487faa663000897 的 LOB 记录删除:

  1. > db.sample.video.deleteLob( '5435e7b69487faa663000897' )