定义

MySQL虚拟列(generated-columns)是MySQL 5.7加入的新特性。怎么理解虚拟列?从名字来讲,“生成的字段”,并不是主动插入的值。

MySQL的文档,是这么解释虚拟列的:

There are two kinds of Generated Columns: virtual (default) and stored. Virtual means that the column will be calculated on the fly when a record is read from a table. Stored means that the column will be calculated when a new record is written in the table, and after that it will be treated as a regular field. Both types can have NOT NULL restrictions, but only a stored Generated Column can be be a part of an index.

解释起来,就是虚拟列支持两种方式,virtual和stored。当在表里读取记录的时候,virtual类型的会进行实时的计算。当写入一条记录的时候,stored类型会通过计算,写入表中,和常规的字段的一样的占用磁盘的空间。这两种类型都可以有NOT NULL限制,但是能使用索引的一部分的功能。

MySQL的官方,提供了一个例子,用来简单的说明虚拟列的作用。

> CREATE TABLE sales(

name VARCHAR(20),

price_eur DOUBLE,

amount INT,

total_eur DOUBLE AS (price_eur * amount),

total_used DOUBLE AS (total_eur * xrate),

xrate DOUBLE);

> INSERT INTO sales(name,price_eur,amount,xrate) VALUES('尺子', 1.2, 10, 0.9);

> SELECT * FROM sales;

name|price_eur|amount|total_eur|total_used|xrate

尺子|1.2|10|12|10.8|0.9

这个例子应该算是比较明了了,total_eur和total_used根据计算的公式,自动计算除了结果。

使用的场景

虚拟列的使用场景其实还算是挺多的,就想上面的例子,可以计算一些公式。尤其对一致性要求比较高的。如果每次都是通过代码进行计算,可能会由于人为的原因,某个字段的计算结果,没有update,那么就会产生bug。如果使用虚拟列,那么直接更新比较的值就好,没必要更新计算结果,降低的人为误操作的风险。

实时计算

举个例子,我们可能会需要记录三角形的三边,即:两个直角边,和一个斜边。

按照一般的逻辑,我们可能会,通过代码直接进行计算

$a = 4;

$b = 3;

$c = sqrt(pow($a, 2) + pow($b, 2));

// 插入到数据库

这样做是可以的,但是可能会由于人为原因,导致计算的步骤有问题,比如由于人为疏忽,导致忘记了把斜边的值更新到数据库。

我们可以通过MySQL创建一个斜边的虚拟列,然后自动进行计算。

> CREATE TABLE `triangle` (

`sidea` double DEFAULT NULL,

`sideb` double DEFAULT NULL,

`sidec` double GENERATED ALWAYS AS (SQRT(sidea * sidea + sideb * sideb))

) ;

数据冗余

这个场景也是比较常见,比如,我们的某个字段存储的是json结构,但是为了方便查询,可能需要json里面的某个子单当做SQL的查询条件,这个时候,我们可以把这个查询条件,作为虚拟列。

使用限制

虚拟列虽然是计算的结果,但是也是有一些限制的。

恶意的数据

> create table t( x int, y int, z int generated always as( x / y));

insert into t(x,y) values(1,0);

1365 - Division by 0, Time: 0.043000s

根据创建的表语句,z是x和y的商,由于要插入的值y=0,导致计算的时候出现了错误。

删除源数据的列

还是以第一个表的数据为例

> CREATE TABLE sales(

name VARCHAR(20),

price_eur DOUBLE,

amount INT,

total_eur DOUBLE AS (price_eur * amount),

total_used DOUBLE AS (total_eur * xrate),

xrate DOUBLE);

> alter table sales drop price_eur;

3108 - Column 'price_eur' has a generated column dependency.

索引的限制

虚拟列是不允许创建主键索引和全文索引的。

> CREATE TABLE sales(

name VARCHAR(20),

price_eur DOUBLE,

amount INT,

total_eur DOUBLE AS (price_eur * amount),

total_used DOUBLE AS (total_eur * xrate),

total_used2 DOUBLE AS (total_eur * xrate) stored,

xrate DOUBLE);

我重新创建了一个表,下面来看看virtual和stored在索引上的区别吧。

> ALTER TABLE sales ADD PRIMARY KEY(total_eur);

3106 - 'Defining a virtual generated column as primary key' is not supported for generated columns.

> ALTER TABLE sales ADD PRIMARY KEY(total_used2);

Query OK, 0 rows affected (0.05 sec)

Records: 0 Duplicates: 0 Warnings: 0

第一个区别就是,virtual是不允许作为主键的,这大概是因为virtual是实时计算的值,并且并没有写到磁盘上,没办法使用聚集索引。

> ALTER TABLE sales ADD fulltext index (total_eur);

3106 - 'Fulltext index on virtual generated column' is not supported for generated columns.

> ALTER TABLE sales ADD fulltext index(total_used2);

1283 - Column 'total_used2' cannot be part of FULLTEXT index

很明显,两者都不能创建全文索引。

总结

虚拟列是MySQL 5.7版本之后新增的特性,主要是方便我们查询和操作。

我所说的可能只是冰山一角,具体的用法,还需要我们自己根据具体的业务场景使用才行。

参考文献

mysql主键generated_MySQL之虚拟列(generated-columns)相关推荐

  1. mysql修改虚拟列属性失败_mysql虚拟列(Generated Columns)及JSON字段类型的使用

    mysql 5.7中有很多新的特性,但平时可能很少用到,这里列举2个实用的功能:虚拟列及json字段类型 一.先创建一个测试表: drop table if exists t_people; CREA ...

  2. mysql虚拟列(Generated Columns)及JSON字段类型的使用

    mysql 5.7中有很多新的特性,但平时可能很少用到,这里列举2个实用的功能:虚拟列及json字段类型 一.先创建一个测试表: 1 2 3 4 5 6 7 8 9 drop table  if ex ...

  3. MySQL主键(PRIMARY KEY)

    "主键(PRIMARY KEY)"的完整称呼是"主键约束".MySQL 主键约束是一个列或者列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键 ...

  4. MySQL||主键(primary key)及主键约束

    主键 主键(PRIMARY KEY)"的完整称呼是"主键约束".MySQL 主键约束是一个列或者列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键,通过 ...

  5. mysql主键_mysql主键是什么?

    在mysql中,主键全称"主键约束",是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性:主键的作用是确定该数据的唯一性,主要是用于和其他表的外键关联, ...

  6. mysql主键干嘛的_mysql主键是什么?

    在mysql中,主键全称"主键约束",是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性:主键的作用是确定该数据的唯一性,主要是用于和其他表的外键关联, ...

  7. mysql 主键溢出检查_详解MySQL 表中非主键列溢出情况监控

    今天,又掉坑了. 之前踩到过MySQL主键溢出的情况,通过prometheus监控起来了. 这次遇到的坑,更加的隐蔽. 是一个log表里面的一个int signed类型的列写满了.快速的解决方法当然还 ...

  8. mysql主键更新被锁_MySQL 的加锁处理,你都了解的一清二楚了吗?

    MySQL加锁分析,一直是一个比较困难的话题. 我在工作过程中,经常会有同事咨询这方面的问题.本文,准备就MySQL加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQ ...

  9. MySQL主键学习总结

    浅谈MySQL主键 主键没有着明确的概念定义,其是索引的一种,并且是唯一性索引的一种,且必须定义为"PRIMARY KEY",主键不能重复,一个表只能有一个主键. 1.声明主键的方 ...

最新文章

  1. 13-计算最长英语单词链
  2. 模拟器中文输入法设置
  3. 深度学习与计算机视觉系列(7)_神经网络数据预处理,正则化与损失函数
  4. window.open 弹出居中窗口
  5. 如何在Chrome development tool里查看C4C前台发送的未经 GZIP 压缩之前的请求细节
  6. abp框架mysql连接配置,abp框架连接数据库
  7. 博世传感器调试笔记(二)加速度及陀螺仪传感器BMI160
  8. Spring核心组件
  9. 有些CAD通过Arcgis程序读取后,发现面积不对
  10. mysql判断用户名和密码是否正确_怎样分别判断用户名和密码是否正确
  11. 电费我来降!5G用电支持十大地方标杆政策梳理
  12. 在线检测本机ip的网站
  13. Linux之问题详解(一):Linux怎么创建一个html文件通过CentOS部署html网站到服务器
  14. 第2章 无人艇局部危险避障算法研究
  15. labview dsn连接mysql_labview使用DSN与数据库的连接包括access,mysql
  16. PayPal开发之IPN的使用
  17. 认证失败,严重错误:无法连接到服务器
  18. 安装和使用PyInstaller生成window的exe和Mac的执行文件
  19. TSN(Temporal Segment Networks)算法笔记
  20. 618 大促运营必看!4 步教你玩转商品运营

热门文章

  1. java.sql.SQLException: sql injection violation, part alway false condition not allow
  2. zip和unzip压缩解压指令 --排除目录
  3. speedtest的原理
  4. Xylan-MAL|木聚糖-马来酰亚胺|木聚糖-聚乙二醇-马来酰亚胺|马来酰亚胺-PEG-木聚糖
  5. NAND闪存改变了现代生活
  6. python小游戏毕设 吃豆人小游戏设计与实现 (源码)
  7. [单片机框架] [app_led] 利用软定时器实现闪烁和呼吸等灯光模式
  8. 合并Dev BPL教程
  9. VR全景创业为了把控风险,如何选择加盟公司?
  10. 用32板实现ps2无线遥控的实时控制