BLOB 不适合存标准 JSON 文本,因其不支持 JSON_EXISTS、JSON_VALUE 等内置函数直接查询,需额外字符集转换,易乱码且性能下降;而 VARCHAR2(32767) 在 MAX_STRING_SIZE=EXTENDED 下更高效。
oracle 12c 中 json 存储用 blob 并不节省空间,反而可能增加开销;真正影响存储效率的是字符集、压缩方式和是否启用 extended data types。
为什么 BLOB 不适合存标准 JSON 文本
BLOB 类型按字节原样存储,不进行字符集转换或长度校验。但 JSON 是 UTF-8(或 AL32UTF8)编码的文本,用 BLOB 存会导致:
- 无法使用
JSON_EXISTS、JSON_VALUE等内置函数直接查询 —— 这些函数只接受CLOB或VARCHAR2输入,对BLOB会报ORA-40476: invalid input value for JSON function - 必须显式调用
UTL_RAW.CAST_TO_VARCHAR2转换后才能解析,多一次内存拷贝 + 字符集解码,性能下降且易出错(比如含非 ASCII 字符时乱码) - BLOB 段默认不启用行内存储(
ENABLE STORAGE IN ROW),小 JSON(CLOB 占更多空间:BLOB 需额外维护 LOB index 和 chunk 元数据
CLOB 才是 Oracle 12c+ 推荐的 JSON 存储类型
Oracle 官方文档明确将 CLOB 列标记为 JSON 存储首选,原因很实际:
-
CLOB在 AL32UTF8 字符集下,中文等 Unicode 字符按 UTF-8 编码存储,与 JSON 规范天然一致,无转换损耗 - 支持
IS JSON约束,能强制保证入库数据合法,避免后期查询时报ORA-40442 - 可直接在
CLOB上建基于函数的索引,例如:CREATE INDEX idx_json_status ON orders (JSON_VALUE(clob_col, '$.status' RETURNING VARCHAR2(20))); - 从 12.2 开始,
CLOB支持 SecureFiles,启用压缩后(COMPRESS MEDIUM)对重复结构的 JSON(如日志、配置)能节省 30%~50% 空间
真正影响 JSON 存储体积的三个关键点
别纠结 BLOB/CLOB,以下操作才决定实际磁盘占用:
-
关闭冗余空白:入库前用
JSON_SERIALIZE(... PRETTY FALSE)压缩空格/换行;默认 Pretty 格式会让体积膨胀 20%~40% -
启用 SecureFiles 压缩:建表时指定
LOB (json_col) STORE AS SECUREFILE (COMPRESS MEDIUM);注意需先设置DB_SECUREFILE = PREFERRED -
突破 4000 字节限制用 Extended 类型:若 JSON 很大(>4KB),确保数据库已启用
MAX_STRING_SIZE=EXTENDED,然后改用VARCHAR2(32767)替代CLOB—— 对小 JSON(VARCHAR2 的访问效率远高于CLOB,且支持普通 B-tree 索引
什么时候才该考虑 BLOB?
仅当满足全部以下条件时,BLOB 才有意义:
- JSON 数据来自外部二进制源(如加密后的 JSON blob、gzip 压缩流),你**不打算在数据库内解析它**,只做透传存储
- 业务逻辑层已自行完成 UTF-8 校验和解压,且确认 Oracle 不参与任何 JSON 函数运算
- 你主动承担后续所有解析成本:每次读取都得写
SELECT UTL_RAW.CAST_TO_VARCHAR2(json_blob) FROM ...,再喂给 PL/SQL 解析器
否则,坚持用 CLOB,配 IS JSON 约束和 SecureFile 压缩 —— 这才是 Oracle 12c 处理 JSON 的正统路径。容易被忽略的是:IS JSON 约束本身不耗空间,但能避免后期因非法 JSON 导致全表扫描失败,这个隐性成本比存储多几百字节高得多。


















