大对象
概念
大对象LOB (Large Object) 的功能是为了突破 SequoiaDB 巨杉数据库的单条记录最大长度为 16MB 的限制,为用户写入和读取更大型记录提供便利。对于文档、图片、音频和视频等非结构化的数据,用户可以使用 LOB 存储。LOB 存放在集合中,每一个 LOB 都需要一个 OID 来唯一标示。LOB 的内容只存放在一个集合中,当集合被删除时,其拥有的 LOB 将自动删除。
存放 LOB 的集合应该满足如下要求:
- 当集合是普通集合,集合只存在某一个数据组中。此时,LOB 的最大容量为集合能使用的最大文件空间。
- 当集合是哈希分区集合,LOB 对该哈希分区集合的 ShardingKey 没有要求。一般情况下,用户在创建哈希分区集合来存放 LOB 时,可以使用 “_id” 键作为 ShardingKey。当集合为哈希分区集合时,集合存在一个或者多个数据组中。在这种情况下,LOB 最大的容量由哈希分区集合使用的数据组的数据决定。
存储结构
LOB 以集合为单位进行存储,因此它保持集合空间和集合的逻辑结构。在磁盘的数据存储中,对应的集合空间会增加 2 个文件:
[CollectionSpace].1.lobm
[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 | × | √ | × | √ | √ | 并发写时需要按写入的数据段加锁并 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 中:
> db.sample.video.putLob( '/opt/video_2019_02_26_1.avi' )
5435e7b69487faa663000897
2.在 Sdb Shell 中查看集合 sample.video
中所有 LOB 及其对应的 OID:
> db.sample.video.listLobs()
{
"Size": 76602,
"Oid": {
"$oid": "5435e7b69487faa663000897"
},
"CreateTime": {
"$timestamp": "2019-02-26-12.51.43.628000"
},
"ModificationTime": {
"$timestamp": "2019-02-26-12.51.45.523000"
},
"Available": true
}
3.在 Sdb Shell 中将集合 sample.video
中的 OID 为 435e7b69487faa663000897
的LOB 下载到本地文件 video_2019_02_26_1_bak.avi
中:
> db.sample.video.getLob( '5435e7b69487faa663000897', '/opt/video_2019_02_26_1_bak.avi' )
4.在 SDB Shell 中将集合 sample.video
中的 OID 为 5435e7b69487faa663000897
的 LOB 记录删除:
> db.sample.video.deleteLob( '5435e7b69487faa663000897' )