什么是虚拟列?

在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默认的方式

特殊用途冗余列

列长度还是和定义类型一样

能正常加索引

查询效率上,物理>STORED>VIRTUAL

应用

这里配合5.7开始支持的json,来体验一下虚拟列的使用

1. 创建表

CREATE TABLE user_info (
  uid INT(11) NOT NULL AUTO_INCREMENT,
  uname VARCHAR(20) NOT NULL DEFAULT '',
  other_info json,
  PRIMARY KEY(uid)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4;

2. 写入数据

## 两种写入json数据方式
INSERT INTO user_info (uname,other_info) VALUES ('first user',JSON_OBJECT("age",22,"real_name","Wayne","sex","男"));        
INSERT INTO user_info (uname,other_info) VALUES ('second user','{"age":21, "real_name":"Jone", "sex":"女", "height":170, "weight":48}');

数据如图:

mysql> select * from user_info where other_info->'$.age'='24';
+-----+------------+---------------------------------------------------+-------+
| uid | uname      | other_info                                        | v_age |
+-----+------------+---------------------------------------------------+-------+
|   1 | first user | {"age": "24", "sex": "男", "real_name": "Wayne"}  |    24 |
+-----+------------+---------------------------------------------------+-------+
1 row in set (0.00 sec)

mysql> select * from user_info where json_extract(other_info,'$.age')='24';
+-----+------------+---------------------------------------------------+-------+
| uid | uname      | other_info                                        | v_age |
+-----+------------+---------------------------------------------------+-------+
|   1 | first user | {"age": "24", "sex": "男", "real_name": "Wayne"}  |    24 |
+-----+------------+---------------------------------------------------+-------+
1 row in set (0.00 sec)

3.增加虚拟列 v_age(养成加前缀的好习惯, 例如这里使用"v_"来标记该字段是一个虚拟字段,在团队开发时,共同遵守一个约定, 相互配合起来会非常顺利)

##默认是Virtual Column,虚拟列不持久化
ALTER TABLE user_info ADD COLUMN v_age TINYINT(3) UNSIGNED GENERATED ALWAYS AS (other_info->'$.age');

更新以后的表结构如下:

4. 查看更新后的数据

可以看到v_age已自动提取了other_info中的age字段

更新一下记录,把id=1的age更新为24

UPDATE user_info SET other_info=json_set(other_info,'$.age','24') WHERE uid=1;

再来看下数据,对应的v_age也更新为24,是不是有点像视图的感觉,哈哈

这里注意一下,insert时不要给虚拟列设定值, 否则会报错(这里就体现出了加前缀的好处,不管是别人还是自己,看到v_前缀就会意识到这是一个虚拟列,就不至于写出类似的错误语句了)

5. 关于索引,json字段无法对其中一个值使用索引,而虚拟列是支持索引的, 可以利用这一特性来索引json字段的某个值

#创建索引
ALTER TABLE user_info ADD INDEX v_age(v_age);

使用explain来查看一下v_age索引的使用情况,可以看到使用的索引的为v_age

https://www.cnblogs.com/nkefww/p/9964874.html

JSON & 虚拟列的更多相关文章

  1. MySQL 5.7 虚拟列 (virtual columns)

    参考资料: Generated Columns in MySQL 5.7.5 MySQL 5.7新特性之Generated Column(函数索引) MySQL 5.7原生JSON格式支持 Gener ...

  2. MySQL 5.7 虚拟列 (virtual columns)(转)

    原文地址:https://www.cnblogs.com/raichen/p/5227449.html 参考资料: Generated Columns in MySQL 5.7.5 MySQL 5.7 ...

  3. [oracle 11g 新特性] virtual column虚拟列

    总结:虚拟列可以使用于一些特殊场合,实质是类似于函数列(即以 表中已有的列 经过函数运算得来),“虚拟列不存储在数据库中,是在执行查询时由oracle后台计算出来返回给用户”,因此虚拟列不会增加存储空 ...

  4. Oracle 11g 虚拟列 Virtual Column介绍

    Oracle 11G 虚拟列 Virtual Column Oracle 11G 在表中引入了虚拟列,虚拟列是一个表达式,在运行时计算,不存储在数据库中,不能更新虚拟列的值. 定义一个虚拟列的语法: ...

  5. Oracle 11g 新特性(一)-- 虚拟列

    数据库版本: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Oracle11g 增加了虚拟列的新特性, 具体说明如 ...

  6. SQL SERVER 中 实现主表1行记录,子表多行记录 整合成一条虚拟列

    表中有这样的记录,简单的主子表,现要想通过left join 语句把两表关联起来 select * from tbl_diary_reback a left join tbl_diary_reback ...

  7. Oracle 11g新特性虚拟列分区

    如今有个需求:一个单据表要依照月份来分区.假设是在Oracle 10g上,仅仅能再加一个字段. 在Oracle 11g以后就不一样了.能够用虚拟列处理. SQL> select * from v ...

  8. 使用mysql5.7新特性(虚拟列)解决使用前通配符性能问题

    众所周知,在mysql里的后通配符可以使用索引查找,前通配查询却无法使用到索引,即使是使用到了索引,也是使用了索引全扫描,效率依然不高,再MySQL5.7之前,一直都没有好的办法解决,但是到了MySQ ...

  9. MariaDB扩展特性--虚拟列

    存在于表中的列,它们的值是根据确定的表达式或者是根据表中其他列的值自动计算的. 虚拟列有两种,分别对应了定义虚拟列的修饰关键词: 'VIRTUAL'修饰词含义为该虚拟列的值会在查询的时候计算生成. ' ...

随机推荐

  1. 【转】adb server is out of date. killing完美解决

    今天,久未出现的著名的“adb server is out of date.  killing”又发生了,在此,将解决方法记下,以便日后查看. 1. 错误信息: C:\Users\lizy>ad ...

  2. F12找到页面某一元素所绑定的点击事件

    比如我要查看银行账号这个标签所绑定的事件. 操作过程中使用的是谷歌浏览器 第一步:在该元素上右键→检查 第二步:点击Event Listeners 这样就能看到该元素绑定的所有事件了 第三步:展开cl ...

  3. 001 centos7中的安装

    以前学习过centos6.4的安装使用,然后新使用centos7,发现有些修改配置变化了,记录一下. 1.修改主机名 查看主机名: 修改: 二:ip的固定 1.参考文章 https://www.jia ...

  4. IDEA中使用Maven:通过模板项目来创建新工程(转)

    首先自己有一个很完善的项目,并想通过这个项目做一个Demo事例项目: 例子1 如下图,在idea的terminal中敲入命令: mvn archetype:create-from-project 1 ...

  5. Java获取系统基础参数信息

    一.JVM已经帮我们读取了系统信息 public void testSystemParam(){ Properties p = System.getProperties(); Iterator it ...

  6. Vue非父子组件传值

    <template> <div id="app"> <v-home></v-home> <br> <hr> ...

  7. 123457123456#2#----com.MC.HuiHuaGame33--前拼后广--画画填色Game-mc

    com.MC.HuiHuaGame33--前拼后广--画画填色Game-mc

  8. linux本地检测tomcat是否启动成功

    @参考文章 原文如下: linux本地检测如何tomcat是否启动成功? 解决方法: 1.curl 127.0.0.1:8080 第一可以知道本地是否可以访问tomcat,返回页面代码 2.tail ...

  9. ABAP DMEO 通过工单号读取内部对象号

    *&---------------------------------------------------------------------* *& Report YDEMO_013 ...

  10. 使用SoapUI测试wsdl

    webservice服务wsdl地址:http://localhost:8080/services/HelloWorld?wsdl new project: new soap project: 调用测 ...