当前位置: 代码迷 >> 综合 >> MySQL 5.7 虚拟列 (virtual columns)
  详细解决方案

MySQL 5.7 虚拟列 (virtual columns)

热度:10   发布时间:2023-12-26 20:01:33.0

Generated 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 Golumn的话,可能在Virtual Generated Column上建立索引更加合适

综上,一般情况下,都使用Virtual Generated Column,这也是MySQL默认的方式

 

语法:

<type> [ GENERATED ALWAYS ] AS ( <expression> ) [ VIRTUAL|STORED ]
[ UNIQUE [KEY] ] [ [PRIMARY] KEY ] [ NOT NULL ] [ COMMENT <text> ]

 

应用:

为了实现对json数据中部分数据的索引查询,可以使用MySQL5.7中的虚拟列(virtual column)功能

创建表

create table user(uid int auto_increment,data json,primary key(uid));

构建数据

insert into user values (NULL,'{"name":"zhang","address":"beijing"}');
insert into user values (NULL,'{"name":"wang","address":"tianjing"}');

构建姓名的虚拟列

语法:
alter table 表名 add column 虚拟列名 varchar(255) GENERATED ALWAYS AS (json_extract(`attach`,'$.虚拟列名')) VIRTUAL;alter table user add user_name varchar(20) generated always as (data->'$.name');修改虚拟键语法:
alter table 表名 modify column 虚拟列名 varchar(255) GENERATED ALWAYS AS (json_extract(`attach`,'$.虚拟列名')) VIRTUAL;

构建索引

alter table user add index idx_name(user_name);

查询

select * from user where user_name='"zhang"';

查询语句可以正常使用索引

通过虚拟列的方式,即满足了查询性能,也不会有之前那个解决方案的潜在麻烦

虚拟列不存储在数据行中,但虚拟列的元数据信息会存在于相关系统表中,对虚拟列的添加或者删除只会涉及这些系统表,不会导致数据表的重建,所以效率很高

 

此时的表的结构由于多出了user_name这一虚拟列,再插入别的数据要注意在表后指明插入列(不能给虚拟列插入数据)

insert into user(uid,data) values (NULL,'{"name":"li","address":"hebei"}');
需要注意,不能建立虚拟列和真实列的联合索引。

 

  相关解决方案