半结构化编码
本文档主要介绍 seekdb 支持的 JSON 数据半结构化编码功能。
seekdb 支持建表时开启半结构化编码,主要由表级别参数 SEMISTRUCT_PROPERTIES 控制,同时也要设置表的 ROW_FORMAT=COMPRESSED,否则会报错。
注意事项
- 当
SEMISTRUCT_PROPERTIES=(encoding_type=encoding)时,表被认为是半结构化表,即整张表中的 JSON 列都会启用半结构化编码; - 当
SEMISTRUCT_PROPERTIES=(encoding_type=none)时,表被认为是结构化表。 - 同时,还支持通过
freq_threshold参数设置频率阈值。当启用半结构化编码时,系统会分析 JSON 数据中各个路径的出现频率,将出现频率高于设定阈值的路径作为独立的子列存储,这些子列就称为频繁列。例如,假设您有一个用户表,JSON 字段存储用户信息,如果 90% 的用户都有name和age字段,那么系统会自动将name和age提取为独立的频繁列,查询时直接访问这些列而不需要解析整个 JSON,从而提升查询性能。 - 当前
encoding_type和freq_threshold是 Online DDL 语法,不支持 Offline DDL 语法。
数据形式
把 JSON 数据按照一定的形式拆分成结构化列的方式存储,那么从 JSON 列拆分出的列被称为子列。子列可以被拆分为不同的类型,包括稀疏列和频繁列。
- 稀疏列:部分 JSON 有,部分 JSON 没有的子列,出现频率低于表级别参数
freq_threshold指定的阈值。 - 频繁列:JSON 中出现频率高于表级别参数
freq_threshold指定的阈值的子列,这些子列会被作为独立的列存储,以提升过滤查询性能。
例如:
{"id": 1001, "name": "n1", "nickname": "nn1"}
{"id": 1002, "name": "n2", "nickname": "nn2"}
{"id": 1003, "name": "n3", "nickname": "nn3"}
{"id": 1004, "name": "n4", "nickname": "nn4"}
{"id": 1005, "name": "n5"}
其中 id 和 name 是每个 JSON 都有的字段,出现频率为 100%,nickname 只有 4 个 JSON 有,出现频率为 80%。
如果 freq_threshold 定义为 100%,那么 nickname 就会被推导为稀疏列,id 和 name 就会被推导为频繁列;如果定义为 80%,那么 nickname、id 和 name 就都会被推导为频繁列。
示例
-
启用半结构化编码
提示如果启用半结构化编码功能,请务必保证配置项 micro_block_merge_verify_level 为默认配置
2,切勿关闭微块合并校验。tab 建表时启用的示例
CREATE TABLE t1( j json)
ROW_FORMAT=COMPRESSED
SEMISTRUCT_PROPERTIES=(encoding_type=encoding, freq_threshold=50);更多语法说明请见 CREATE TABLE。
tab 修改已有表来启用半结构化编码的示例
CREATE TABLE t1(j json);
ALTER TABLE t1 SET ROW_FORMAT=COMPRESSED SEMISTRUCT_PROPERTIES = (encoding_type=encoding, freq_threshold=50);更多语法说明请见 ALTER TABLE。
一些修改限制:
- 修改频繁列阈值,如果没开启半结构化不报错,但是不生效。
- 在旁路导入或表被锁定时,
freq_threshold参数无法修改。 - 修改其中一个子配置项,不影响其余的子配置项。
-
关闭半结构化编码
当
SEMISTRUCT_PROPERTIES设置为(encoding_type=none)时,将关闭半结构化编码。此操作不会影响已有的数据,仅对后续写入的数据生效。以下是关闭半结构化编码的示例:ALTER TABLE t1 SET ROW_FORMAT=COMPRESSED SEMISTRUCT_PROPERTIES = (encoding_type=none); -
查询半结构编码配置
通过
SHOW CREATE TABLE语句查询半结构化编码配置。示例语句如下:SHOW CREATE TABLE t1;返回结果如下:
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`j` json DEFAULT NULL
) ORGANIZATION INDEX DEFAULT CHARSET = utf8mb4 ROW_FORMAT = COMPRESSED COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE ENABLE_MACRO_BLOCK_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 SEMISTRUCT_PROPERTIES=(ENCODING_TYPE=ENCODING, FREQ_THRESHOLD=50) |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set当
SEMISTRUCT_PROPERTIES=(encoding_type=encoding)时,查询才会显示该配置项信息,表示开启了半结构化编码功能。使用半结构化编码可以提高 JSON_VALUE() 函数 条件过滤查询的性能。基于 JSON 半结构化编码技术,seekdb 对
JSON_VALUE表达式条件过滤查询场景进行了性能优化。由于 JSON 数据已被拆分为子列,系统可以直接基于编码后 的子列数据进行过滤,无需还原完整的 JSON 结构,从而显著提升查询效率。查询示例如下:
-- 查询 name 字段值为 'Devin' 的行
SELECT * FROM t WHERE JSON_VALUE(j_doc, '$.name' RETURNING CHAR) = 'Devin';字符集注意事项如下:
-
seekdb 的 JSON 使用
utf8_bin编码。 -
为确保字符串白盒过滤正常工作,建议设置:
SET @@collation_server = 'utf8mb4_bin';
SET @@collation_connection='utf8mb4_bin'; -