mysql主键generated_MySQL之虚拟列(generated-columns)
定义
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)相关推荐
- mysql修改虚拟列属性失败_mysql虚拟列(Generated Columns)及JSON字段类型的使用
mysql 5.7中有很多新的特性,但平时可能很少用到,这里列举2个实用的功能:虚拟列及json字段类型 一.先创建一个测试表: drop table if exists t_people; CREA ...
- mysql虚拟列(Generated Columns)及JSON字段类型的使用
mysql 5.7中有很多新的特性,但平时可能很少用到,这里列举2个实用的功能:虚拟列及json字段类型 一.先创建一个测试表: 1 2 3 4 5 6 7 8 9 drop table if ex ...
- MySQL主键(PRIMARY KEY)
"主键(PRIMARY KEY)"的完整称呼是"主键约束".MySQL 主键约束是一个列或者列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键 ...
- MySQL||主键(primary key)及主键约束
主键 主键(PRIMARY KEY)"的完整称呼是"主键约束".MySQL 主键约束是一个列或者列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键,通过 ...
- mysql主键_mysql主键是什么?
在mysql中,主键全称"主键约束",是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性:主键的作用是确定该数据的唯一性,主要是用于和其他表的外键关联, ...
- mysql主键干嘛的_mysql主键是什么?
在mysql中,主键全称"主键约束",是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性:主键的作用是确定该数据的唯一性,主要是用于和其他表的外键关联, ...
- mysql 主键溢出检查_详解MySQL 表中非主键列溢出情况监控
今天,又掉坑了. 之前踩到过MySQL主键溢出的情况,通过prometheus监控起来了. 这次遇到的坑,更加的隐蔽. 是一个log表里面的一个int signed类型的列写满了.快速的解决方法当然还 ...
- mysql主键更新被锁_MySQL 的加锁处理,你都了解的一清二楚了吗?
MySQL加锁分析,一直是一个比较困难的话题. 我在工作过程中,经常会有同事咨询这方面的问题.本文,准备就MySQL加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQ ...
- MySQL主键学习总结
浅谈MySQL主键 主键没有着明确的概念定义,其是索引的一种,并且是唯一性索引的一种,且必须定义为"PRIMARY KEY",主键不能重复,一个表只能有一个主键. 1.声明主键的方 ...
最新文章
- 13-计算最长英语单词链
- 模拟器中文输入法设置
- 深度学习与计算机视觉系列(7)_神经网络数据预处理,正则化与损失函数
- window.open 弹出居中窗口
- 如何在Chrome development tool里查看C4C前台发送的未经 GZIP 压缩之前的请求细节
- abp框架mysql连接配置,abp框架连接数据库
- 博世传感器调试笔记(二)加速度及陀螺仪传感器BMI160
- Spring核心组件
- 有些CAD通过Arcgis程序读取后,发现面积不对
- mysql判断用户名和密码是否正确_怎样分别判断用户名和密码是否正确
- 电费我来降!5G用电支持十大地方标杆政策梳理
- 在线检测本机ip的网站
- Linux之问题详解(一):Linux怎么创建一个html文件通过CentOS部署html网站到服务器
- 第2章	无人艇局部危险避障算法研究
- labview dsn连接mysql_labview使用DSN与数据库的连接包括access,mysql
- PayPal开发之IPN的使用
- 认证失败,严重错误:无法连接到服务器
- 安装和使用PyInstaller生成window的exe和Mac的执行文件
- TSN(Temporal Segment Networks)算法笔记
- 618 大促运营必看!4 步教你玩转商品运营
热门文章
- java.sql.SQLException: sql injection violation, part alway false condition not allow
- zip和unzip压缩解压指令 --排除目录
- speedtest的原理
- Xylan-MAL|木聚糖-马来酰亚胺|木聚糖-聚乙二醇-马来酰亚胺|马来酰亚胺-PEG-木聚糖
- NAND闪存改变了现代生活
- python小游戏毕设 吃豆人小游戏设计与实现 (源码)
- [单片机框架] [app_led] 利用软定时器实现闪烁和呼吸等灯光模式
- 合并Dev BPL教程
- VR全景创业为了把控风险,如何选择加盟公司?
- 用32板实现ps2无线遥控的实时控制