基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
注意
如果启用半结构化编码功能,请务必保证集群配置项 micro_block_merge_verify_level 为默认配置 2 ,切勿关闭微块合并校验。
更新时间:2026-07-28
本文档介绍了 OceanBase 数据库中半结构化存储的最佳实践,重点阐述如何通过半结构化编码存储技术降低 JSON 数据的存储成本。通过合理的配置和使用方法,用户可以在保证数据完整性的同时,显著减少存储空间占用。
目前 JSON 等半结构化的数据,存在下面两个主要问题:
为解决这些问题,OceanBase 引入了半结构化编码存储技术。该技术通过将 JSON 数据结构化存储,不仅显著提升存储效率,还提供了高效的字段查询能力。
OceanBase 的半结构化编码存储技术通过将 JSON 数据拆分为多个子列进行存储,每个子列单独编码,从而提高编码压缩率,降低整体存储空间需求。
示例说明如下:
原始JSON数据:
{"id": 11111001, "name": "white", "score": 85.2}
{"id": 11111002, "name": "brown", "score": 93.5}
{"id": 11111003, "name": "mike", "score": 67.8}
{"id": 11111004, "name": "trump", "score": 72.0}
拆分后存储形式:
| id | name | score |
| -------- | ----- | ----- |
| 11111001 | white | 85.2 |
| 11111002 | brown | 93.5 |
| 11111003 | mike | 67.8 |
| 11111004 | trump | 72.0 |
通过这种方式,系统可以对每列数据应用特定类型的高效编码方案,显著提高压缩率。
半结构化编码存储使用方式,及条件查询性能优化说明请参见使用半结构化编码。
如果启用半结构化编码功能,请务必保证集群配置项 micro_block_merge_verify_level 为默认配置 2 ,切勿关闭微块合并校验。
{"c1": "v1", "c2": "v2"}
{"c1": "v1", "c3": ["v121", "v22"]}
{"c1": "v3", "c2": "v5"}
{"c1": "v4", "c4": ["v121", "v22"]}
在处理此类数据时,由于字段 c1 出现频率很高,系统可将其识别为高频字段,并自动提取为单独列(column),采用高效的编码方式进行存储。这种方式有助于显著降低磁盘占用,并提升查询性能。
由于存在一些不适合的场景,半结构化编码并非在所有场景都会触发,以下情况不会触发:
无法提取公共 schema 的示例如下:
# 字段完全不同
{"c1": "v1", "c2": "v2"}
{"x1": "v1", "x2": "v2"}
我们对半结构化编码存储的性能进行了全面测试,包括存储空间和条件查询性能两个维度。测试使用了标准的 TPC-H 数据集,并与多种主流数据库系统进行了对比,以验证半结构化编码的实际效果。
| 存储类型 | 存储空间 | 条件查询(s) |
|---|---|---|
| 关系表 | 387.086MB | 0.094 |
| 半结构化 JSON | 438.405MB | 0.223 |
| JSON Binary | 764.124MB | 24.445 |
| MongoDB | 1.32GB | - |
| Lindorm | 639MB | - |
| HBase | 1.23GB | - |
| MySQL | 2.10GB | - |
关键发现如下:
此功能从 V4.3.5 BP2 开始支持。
针对时序场景,OceanBase 基于 JSON 半结构化存储提供了优化的 OBKV-HBase 时序数据模式,有效解决原生模型中 K、T 字段重复存储的问题。
数据转换示例如下:
原始数据:
#
{"K": "name1", "T": 1732206353081, "cf1:QualifierA": "v1"}
{"K": "name1", "T": 1732206353081, "cf1:QualifierB": "v2"}
{"K": "name2", "T": 1732206353082, "cf1:QualifierC": "v3"}
{"K": "name2", "T": 1732206353082, "cf1:QualifierD": "v4"}
优化后 OBKV-HBase 存储格式:
| K | Q | T | V |
| ------- | ---------- | ------------- | ---- |
| name1 | QualifierA | 1732206353081 | v1 |
| name1 | QualifierB | 1732206353081 | v2 |
| name2 | QualifierC | 1732206353082 | v3 |
| name2 | QualifierD | 1732206353082 | v4 |
在时序场景下,原始数据中 K(行键)和 T(时间戳)字段会大量重复,特别是在一次 put 操作写入多个单元格时,K 和 T 字段完全相同,导致严重的磁盘空间浪费。同时,如果每个 V 值中包含大量重复的 Qualifier(列限定符),也会进一步增加存储开销。
通过半结构化编码,我们可以:
基于这些优化,我们调整了 OBKV-HBase 的存储格式。以示例数据为例,重新生成后的数据结构如下:
-- S 为该 cell 插入的当前服务端时间
| K | T | S | V |
| ------- | ------------- | ------------- | ---------------------------------- |
| name1 | 1732206353081 | 1732206353081 | {"QualifierA":v1, "QualifierB":v2} |
| name2 | 1732206353082 | 1732206353082 | {"QualifierC":v3, "QualifierD":v4} |
我们对 OBKV-HBase 时序模型存储效率进行了测试:
| 存储类型 | 磁盘占用 |
|---|---|
| 半结构化时序模型 | 466.24MB |
| 普通时序模型 | 654.78MB |
半结构化编码存储技术具有广泛的适用性和扩展性,未来 OceanBase 可能会扩展到 GIS/Array/Vector 等其他多模类型使用。这些扩展将基于现有的半结构化编码技术,进一步提升 OceanBase 多模数据处理方面的能力,为用户提供更全面的数据存储和查询解决方案。
这里介绍了通用的存储空间查询方法。
-- 获取 tablet_id
SELECT tablet_id FROM oceanbase.CDB_OB_TABLE_LOCATIONS
WHERE tenant_id=xxxx AND table_name='xxxxx';
-- 查询存储空间
SELECT size/1024.0/1024.0 FROM oceanbase.GV$OB_SSTABLES
WHERE tenant_id=xxxx AND tablet_id=xxxxx;
-- 获取 tablet_id
SELECT tablet_id FROM oceanbase.DBA_OB_TABLE_LOCATIONS
WHERE table_name='xxxxx';
-- 查询存储空间
SELECT size/1024.0/1024.0 FROM oceanbase.GV$OB_SSTABLES
WHERE tablet_id=xxxxx;