动态可扩展查询MYSQL5.7JSON+虚拟列+Mybatis
背景:现有业务扩展字段,都存在feature字段,存在语义不清晰以及,难以利用索引查询问题
Mysql 5.7后推出利器,JSON+虚拟列,即实现了业务语义统一,也支持索引查询加速
一、简单描述
MySQL 5.7.7 labs版本开始InnoDB存储引擎已经原生支持JSON格式,该格式不是简单的BLOB类似的替换。原生的JSON格式支持有以下的优势:
- JSON数据有效性检查:BLOB类型无法在数据库层做这样的约束性检查
- 查询性能的提升:查询不需要遍历所有字符串才能找到数据
- 支持索引:通过虚拟列的功能可以对JSON中的部分数据进行索引
二、MYSQL JSON 函数支持
http://dev.mysql.com/doc/refman/5.7/en/json-function-reference.html
三、MYBATIS 动态支持扩展+JSON查询
- Mybatis查询
<if test="extendFieldsMap != null and extendFieldsMap.size()>0">
<foreach item="item" index="key" collection="extendFieldsMap"
open="" separator="AND" close="">
<![CDATA[
and JSON_UNQUOTE(extended_fields->'$.${key}')= #{item}
]]>
</foreach>
</if>
- MAP参数传入
- DB 数据存储,格式JSON
四、虚拟列
除了mysql5.7对json特性支持以外,另一个让人振奋人心的莫过于新增了虚拟列的这样一个东西。顾名思义,virtual column就是一个虚拟列,在MySQL 5.7中,支持两种generated column,即virtual generated column和stored generated column,前者只将generated column保存在数据字典中(表的元数据),并不会将这一列数据持久化到磁盘上;后者会将generated column持久化到磁盘上,而不是每次读取的时候计算所得。很明显,后者存放了可以通过已有数据计算而得的数据,需要更多的磁盘空间,与virtual column相比并没有优势,因此,MySQL 5.7中,不指定generated column的类型,默认是virtual column。此外
-
stored generated column性能较差
如果需要stored generated column的话,可能在generated column上建立索引更加合适 知道了什么是虚拟列,那么虚拟索引列当然是虚拟列加上索引喽!当然了,虚拟索引列也是通过传统的B+树索引即可实现对JSON格式部分属性的快速查询。使用方法是首先创建该虚拟列,然后在该虚拟列上创建索引:
ALTER TABLE ding_ding ADD virtualAppId int GENERATED ALWAYS AS (json_extract(instValue,'$.appId')) VIRTUAL;
ALTER TABLE ding_ding ADD index index_virtual_appId (virtualAppId); -
下面看一下官方文档对virtual和stored解释:
VIRTUAL : Column values are not stored, but are evaluated when rows are read, immediately after any BEFORE triggers. 列值不存储,而是被读取行时进行评估,之后立即用 BEFORE触发器。虚拟列不带存储。
STORED : Column values are evaluated and stored when rows are inserted or updated. 列值进行评估,并行被插入或更新时存储。存放的列确实需要的存储空间,并可以被索引。 > 友情提示: > - 在MySQL 5.7.8之前,虚拟列不能建立索引。在MySQL 5.7.8,InnoDB的支持在虚拟列辅助索引 > - json类型字段不支持直接索引 > - 虚拟索引列只支持二级索引,其它的索引类型不支持 > - 虚拟索引列不能被当做一个外键来使用 > - 添加或在虚拟列删除一个辅助索引是就地操作。 Adding or dropping a secondary index on a virtual column is an in-place operation.