MySQL 8 JSON多值索引

MySQL 8 JSON多值索引

背景介绍

我们有个 node model,对应的存储表名也叫 node。这个model里面,有一些复杂配置,是用 json 的格式存储的。这个json配置里面,有个字段会指向另一个node,所以在删除某个node的时候需要检查这个node是否被引用了,如果被引用则不允许删除。这个检查操作,不可能是全表扫描,因此需要创建索引。于是就有了要给 JSON 字段创建多值索引的需求。

建表 & 索引

表的schema就不放这里了,主要是有个叫 units_json 字段,其它不重要。

然后创建索引,注意这里是多值,所以用了ARRAY

ALTER TABLE `node`  
ADD INDEX `jump_node_code_index`( 
    (CAST(units_json -> '$.units[*].decisionEntries[*].capsules[*].jumpNodeCode' 
          AS CHAR(50) ARRAY)) 
);
上面那个 $.units[*]... 是 jsonPath 的定义语法,不了解的同学可以自行谷歌一下。

查询

MySQL 8 中,JSON_EXTRACT 函数可以用 -> 操作符表示。下面这个查询语句,可以将所有 jumpNodeCode 查出来,也就是所有的跳转节点。

SELECT units_json -> '$.units[*].decisionEntries[*].capsules[*].jumpNodeCode' 
FROM   node;

条件查询

下面这个查询语句使用了 MEMBER OF 作为条件。意思是将所有引用了 xxxNode 的节点全部查出来。这个查询语句将用于删除检查。

SELECT node_id, `code`, `name` FROM node
WHERE 'xxxNode' MEMBER OF (units_json -> '$.units[*].decisionEntries[*].capsules[*].jumpNodeCode');

编写jOOQ 工具类

我们项目的ORM框架使用jOOQ,国内相对MyBatis而言小众很多。但我比较喜欢用jOOQ,感兴趣的同学可自行谷歌。
jOOQ 没有提供MySQL这种比较复杂语法,于是自行封装了个工具类

public class JooqSyntax {  
    /**  
 * * @param value 检查值  
 * @param field 列  
 * @param jsonPath json文档语法  
 * @return jooq 条件  
 */  
 public static Condition memberOfCondition(Object value, TableField field, String jsonPath) {  
        return DSL.condition("{0} MEMBER OF ({1})", value, jsonField(field, jsonPath)  
        );  
 }  
  
    public static Field jsonField(TableField field, String jsonPath) {  
        return DSL.field("{0} -> {1}", field, jsonPath);  
 }  
} 
 

单元测试,主要是用于说明如何使用。

public class JooqSyntaxTest {  
  
    @Test  
     void test() {  
        DSLContext ctx = DSL.using(SQLDialect.MYSQL);  
  
         Condition condition = JooqSyntax.memberOfCondition(1, TOPIC.PERMISSION_JSON, "$.xxx");  
     System.out.println(  
                ctx.selectFrom(TOPIC)  
                        .where(condition)  
        );  
  
     System.out.println(ctx  
                .select(JooqSyntax.jsonField(TOPIC.PERMISSION_JSON, "$.xxx"))  
                .from(TOPIC)  
        );  
 }  
}

相关参考:
MySQL 8.0 新特性:多值索引 --如何给JSON数组添加索引(三)
MySQL :: MySQL 8.0 Reference Manual :: 11.5 The JSON Data Type

你可能感兴趣的:(mysqljson索引)