mysql虚拟列Generated Column

目录​​​​​​​

1、Generated Column简介

生成的列定义具有以下语法:

2、实践

2.1 存储格式为json字段增加索引

2.2 手机号后四位

3、虚拟列索引介绍

3.1 虚拟列索引的限制

3.1.1 Virtal Generated Column

4、阿里云数据库环境是否支持

下期扩展:

1、MySQL InnoDB Cluster

2、MySQL NDB Cluster

参考文档


1、Generated Column简介

MySQL 5.7引入Generated Column(生成列、虚拟列、虚拟生成列索引函数):根据列定义中包含的表达式计算得出

生成列包含下面两种类型:

Virtual Generated Column(虚拟):当从表中读取记录时,将动态计算该列。保存在数据字典中(表的元数据),并不会将这一列数据持久化到磁盘上。(MySQL 5.7中默认是Virtual Generated Column)

Stored Generated Column(存储):当向表中写入新记录时,将计算该列并将其存储为常规列。

virtual生成列比stored生成列更有用,因为一个虚拟的列不占用任何存储空间。你可以使用触发器模拟stored生成列的行为。

用法举例

drop TABLE triangle;
CREATE TABLE triangle
(sidea DOUBLE,sideb DOUBLE,sidec DOUBLE AS (SQRT(sidea * sidea + sideb * sideb))
);
select * from triangle;
INSERT INTO triangle (sidea, sideb) VALUES(1,1),(3,4),(6,8);

sidec边为虚拟列。插入c的值为动态计算如下图:

一般情况下,都使用Virtual Generated Column,这也是MySQL默认的方式,如果使用Stored Generated Column,前面的建表语句将会是下面这样,即多了一个STORED关键字.

CREATE TABLE `triangle`
(`sidea` double DEFAULT NULL,`sideb` double DEFAULT NULL,`sidec` double GENERATED ALWAYS AS (SQRT(sidea * sidea + sideb * sideb)) STORED
);

生成的列定义具有以下语法:

col_name data_type [GENERATED ALWAYS] AS (expr)[VIRTUAL | STORED] [NOT NULL | NULL][UNIQUE [KEY]] [[PRIMARY] KEY][COMMENT 'string']

AS (expr) 指示生成列并定义用于计算列值的表达式。AS 可以在前面加上GENERATED ALWAYS以使生成的列的性质更加明确(区分其他列)。

VIRTUALor关键字指示如何存储列值, 这STORED 对列的使用有影响:

  • VIRTUAL: 不存储列值,而是在读取行时,在任何 BEFORE触发器之后立即评估。虚拟列不占用存储空间、InnoDB支持虚拟列的二级索引。(默认)
  • STORED:在插入或更新行时评估和存储列值。存储列确实需要存储空间并且可以被索引。

允许在同一个表中混合VIRTUAL列 STORED。

生成列的规则和限制:

  • 允许使用文字、确定性内置函数和运算符。如果给定表中的相同数据,则函数是确定性的,多次调用产生相同的结果,独立于连接的用户。非确定性且不符合此定义的函数示例:CONNECTION_ID(), CURRENT_USER(), NOW().
  • 不允许存储函数和可加载函数。
  • 不允许使用存储过程和函数参数。
  • 不允许使用变量(系统变量、用户定义变量和存储的程序局部变量)。
  • 不允许子查询。
  • 生成的列定义可以引用其他生成的列,但只能引用表定义中较早出现的列。生成的列定义可以引用表中的任何基本(非生成)列,无论其定义发生得早还是晚。
  • 该AUTO_INCREMENT属性不能在生成的列定义中使用。
  • AUTO_INCREMENT列不能用作生成的列定义中的基列 。
  • 从 MySQL 5.7.10 开始,如果表达式求值导致截断或向函数提供不正确的输入,则 CREATE TABLE语句以错误终止并且 DDL 操作被拒绝。

生成的列作用:

  • 虚拟生成的列可用作简化和统一查询的一种方式。一个复杂的条件可以定义为一个生成的列,并从对表的多个查询中引用,以确保它们都使用完全相同的条件。
  • 存储的生成列可以用作复杂条件的物化缓存,这些条件在运行时计算成本很高。
  • 生成列可以模拟函数索引:使用生成列定义函数表达式并对其进行索引。这对于处理无法直接索引的类型的列(例如 JSON列)很有用;有关详细示例, 请参阅 索引生成的列以提供 JSON 列索引。对于存储生成的列,这种方法的缺点是值被存储了两次;一次作为生成列的值,一次在索引中。
  • 如果生成的列被索引,优化器会识别与列定义匹配的查询表达式,并在查询执行期间适当地使用列中的索引,即使查询不直接按名称引用列。有关详细信息,请参阅 第 8.3.10 节,“优化器使用生成的列索引”。

2、实践

2.1 存储格式为json字段增加索引

之前日志存储都是采用json,因此本次使用的存储json字段相关表

json解析的方法:

-> MySQL 5.7.9 及更高版本支持 该 运算符。->> 从 MySQL 5.7.13 开始支持 该 运算符。

请参阅 -> and ->> 运算符以及 JSON_EXTRACT()and JSON_UNQUOTE()函数的说明

-- json_extract和->>的区别 ,json_extract解析出的带双引号 两种解析中文和数字貌似都需要带双引号
select json_extract(params,'$."联系方式"') as tel from execute_log;
select json_extract(params,'$.name') from execute_log;SELECT params->>'$."联系方式"' AS tel from execute_log;
-- 英文不用双引号
SELECT params->>'$.name' AS tel from execute_log;

虚拟生成列新增:

-- 删除虚拟列
ALTER TABLE execute_log DROP COLUMN `mobile`;
-- 添加联系方式的虚拟列
alter table execute_log add mobile varchar(20) generated always as (params->>'$."联系方式"') stored after params;
-- 新增索引
alter table execute_log add index idx_mobile(mobile);

执行查询后:

当然在实际使用过程中,索引都是带companyId的

-- 新增公司和手机号索引
alter table execute_log add index idx_company_mobile(company_id,mobile);

2.2 手机号后四位

-- 添加联系方式后4位的虚拟列
alter table test_table add right4Mobile varchar(20) generated always as (RIGHT (mobile,4)) stored after mobile ;
-- 删除虚拟列
ALTER TABLE test_table DROP COLUMN `right4Mobile`;
-- 添加联合索引
alter table test_table add index idx_company_right4Mobile(company_id,right4Mobile);

性能对比 数据集:1004177(百万)

是否添加虚拟列

执行sql

耗时

select * from test_table where company_id = 6 and mobile like '%1800';

109 rows retrieved starting from 1 in 5 s 83 ms (execution: 2 s 911 ms, fetching: 2 s 172 ms)

select * from test_table where company_id = 6 and right4Mobile = '1800';

109 rows retrieved starting from 1 in 160 ms (execution: 72 ms, fetching: 88 ms)

添加虚拟列过程记录备份:

demo> alter table test_table add right4Mobile varchar(10) generated always as (RIGHT (mobile,4)) after mobile [2022-01-19 20:22:07] 
completed in 3 s 101 ms 
demo> alter table test_table add index idx_company_right4Mobile(company_id,right4Mobile) [2022-01-19 20:22:26] 
completed in 6 s 91 ms 


3、虚拟列索引介绍

InnoDB支持虚拟生成列的二级索引。不支持其他索引类型。在虚拟列上定义的二级索引有时称为“虚拟索引”。

二级索引可以在一个或多个虚拟列或虚拟列和常规列的组合或存储的生成列上创建。包含虚拟列的二级索引可以定义为UNIQUE.

在虚拟生成列上创建二级索引时,生成的列值会在索引的记录中具体化。如果索引是 覆盖索引(包括查询检索到的所有列),则从索引结构中的物化值中检索生成的列值,而不是“即时”计算。

When a secondary index is created on a virtual generated column, generated column values are materialized in the records of the index. If the index is a covering index (one that includes all the columns retrieved by a query), generated column values are retrieved from materialized values in the index structure instead of computed “on the fly”.

covering index(不回表)

An index that includes all the columns retrieved by a query. Instead of using the index values as pointers to find the full table rows, the query returns values from the index structure, saving disk I/O. InnoDB can apply this optimization technique to more indexes than MyISAM can, because InnoDB secondary indexes also include the primary key columns. InnoDB cannot apply this technique for queries against tables modified by a transaction, until that transaction ends.

Any column index or composite index could act as a covering index, given the right query. Design your indexes and queries to take advantage of this optimization technique wherever possible.

See Also column index, composite index, index, primary key, secondary index.

INSERT由于在和 UPDATE操作 期间实现二级索引记录中的虚拟列值时执行的计算,在虚拟列上使用二级索引时需要考虑额外的写入成本。即使有额外的写入成本,虚拟列上的二级索引也可能比生成的存储列更可取,后者在聚集索引中具体化,从而导致需要更多磁盘空间和内存的更大表。如果未在虚拟列上定义二级索引,则读取会产生额外成本,因为每次检查列的行时都必须计算虚拟列值。

索引虚拟列的值是 MVCC 记录的,以避免在回滚或清除操作期间对生成的列值进行不必要的重新计算。记录值的数据长度受索引键的限制,对于和行格式为 767 字节,对于 和 COMPACT行REDUNDANT格式为 3072 字节。 DYNAMICCOMPRESSED

在虚拟列上添加或删除二级索引是就地操作。( Adding or dropping a secondary index on a virtual column is an in-place operation.)

在 5.7.16 之前,外键约束不能引用在虚拟生成列上定义的二级索引。

在 MySQL 5.7.13 和更早版本中,InnoDB不允许在索引生成的虚拟列的基列上定义具有级联引用操作的外键约束。MySQL 5.7.14 中取消了此限制。

3.1 虚拟列索引的限制

3.1.1 Virtal Generated Column

  • 聚集索引不能包含Virtual generated column
create table t1(a int, b int , c int GENERATED ALWAYS AS (a / b), primary key(c))[HY000][3106] 'Defining a virtual generated column as primary key' is not supported for generated columns.-- STORED 可以
create table t1(a int, b int , c int GENERATED ALWAYS AS (a / b) STORED, primary key(c))completed in 168 ms
  • Virtual Generated Column不能作为外键(在 5.7.16 之前,外键约束不能引用在虚拟生成列上定义的二级索引。在 MySQL 5.7.13 和更早版本中,InnoDB不允许在索引生成的虚拟列的基列上定义具有级联引用操作的外键约束。MySQL 5.7.14 中取消了此限制。)

创建generated column(包括virtual generated column 和stored generated column)时不能使用非确定性的(不可重复的)函数,如下curtime()

create table t1(a int, b int , c int GENERATED ALWAYS AS (a / b) STORED, primary key(c));[HY000][3763] Expression of generated column 'p3' contains a disallowed function: curtime.ALTER TABLE `t1` ADD p3 DATE GENERATED ALWAYS AS (curtime()) stored; [HY000][3763] Expression of generated column 'p3' contains a disallowed function: curtime.
  • 不能在Virtual Generated Column上创建全文索引和空间索引(后面版本有望解决)

4、阿里云数据库环境是否支持

下期扩展:

1、MySQL InnoDB Cluster

2、MySQL NDB Cluster

参考文档

1、MySQL :: MySQL 5.7 Reference Manual :: 13.1.18.7 CREATE TABLE and Generated Columns

2、RDS MySQL AliSQL内核小版本发布记录_云数据库 RDS(RDS)-阿里云帮助中心

文章写于2022年01月19日 语雀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/755031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大话适航(一)民航产业

0. 前言 eVTOL、飞行汽车和低空经济已成为热门话题,政府引导资本投入新赛道,也势必会吸引跨界厂商前来淘金。只说民用航空器整机制造,技术最接近的行业是军工,然后是无人机,还有汽车、农业机械等。“互联网”曾经掀起…

数据库应用:Linux 部署 GaussDB

目录 一、实验 1.环境 2.Linux 部署 GaussDB 3.Linux 使用 GaussDB 4.使用 GaussDB 进行表与索引操作 5.使用 GaussDB 进行视图操作 6.使用 GaussDB 进行联表查询 7.使用 GaussDB 进行外键关联 二、问题 1.运行python脚本报错 2. 安装GaussDB 报错 3. install 安装…

语音识别:whisper部署服务器,可远程访问,实时语音转文字(全部代码和详细部署步骤)

Whisper是OpenAI于2022年发布的一个开源深度学习模型,专门用于语音识别任务。它能够将音频转换成文字,支持多种语言的识别,包括但不限于英语、中文、西班牙语等。Whisper模型的特点是它在多种不同的音频条件下(如不同的背景噪声水…

[C语言]指针详解一、数组指针、二维数组传参、函数指针

一、数组指针 对一个数组&#xff0c;如果我们想要让一个指针指向这个数组&#xff0c;我们应该如何定义呢?我们知道一个数组定义本来就是一个指针&#xff0c;那为何要多定义一个数组指针呢?我们来看看下面这个代码就理解了 #include <stdio.h> int main() {int arr…

【基础】哪个厂家的零件更标准?

时间限制 : 1 秒 内存限制 : 128 MB 在统计描述中,方差用来计算每一个变量(观察值)与总体均数之间的差异。比如:甲乙 2 个厂商生产某零件,一批零件要求在尺寸合格的情况下,大小越一致越好,由于生产工艺的问题,零件生产厂商生产的零件不可能一模一样。 为了检测甲乙两…

AIX系统下挂载ISO镜像

我们需要将AIX的iso文件作为软件包的安装源挂载的系统目录中 首先我们查看系统下有哪些挂载文件 如何挂载一个系统iso镜像文件 loopmount -i /ftp/iso/LK4T_1807_11.iso -o "-V cdrfs -o ro " -m /mnt/iso 需要安装软件直接执行smit就可以了&#xff0c;在smit中…

phpStudy安装thinkCMF8时,如何解决服务器rewrite和APIrewrite不支持的问题

解决步骤&#xff1a; 一&#xff1a;服务器rewrite 点击后面的问号跳转到官方文档链接&#xff1a; 复制红框内的代码 打开phpstudy&#xff0c;找到配置的站点&#xff0c;点击管理&#xff0c;找到伪静态 点击确认保存即可。 phpstudy会自动重启站点。 此时&#xff0c;…

docker init 生成Dockerfile和docker-compose.yml —— 筑梦之路

官网&#xff1a;https://docs.docker.com/engine/reference/commandline/init/ 简介 docker init是一个命令行实用程序&#xff0c;可帮助初始化项目中的 Docker 资源。.dockerignore它根据项目的要求创建 Dockerfile、Compose 文件。这简化了为项目配置 Docker 的过程&#…

PHP反序列化---字符串逃逸(增加/减少)

一、PHP反序列化逃逸--增加&#xff1a; 首先分析源码&#xff1a; <?php highlight_file(__FILE__); error_reporting(0); class A{public $v1 ls;public $v2 123;public function __construct($arga,$argc){$this->v1 $arga;$this->v2 $argc;} } $a $_GET[v…

探索区块链世界:从加密货币到去中心化应用

相信提到区块链&#xff0c;很多人会想到比特币这样的加密货币&#xff0c;但实际上&#xff0c;区块链技术远不止于此&#xff0c;它正在深刻地改变我们的生活和商业。 首先&#xff0c;让我们来简单了解一下什么是区块链。区块链是一种分布式数据库技术&#xff0c;它通过将…

蓝桥杯-python-递归

递归&#xff1a;通过自我调用解决问题的函数 注意&#xff1a; #1.递归出口 #2.当前问题如何变成子问题 例子&#xff1a;利用递归写一个阶乘函数&#xff0c;F(n),求n的阶乘 def f(n):if n < 1:return 1ans n * f(n-1)return ans print(f(5)) 例子&#xff1a;汉诺塔…

vsto excel 插件注册表属性值含义

在 VSTO (Visual Studio Tools for Office) 中&#xff0c;LoadBehavior 是用于指定 Office 插件加载行为的一个属性。具体含义如下&#xff1a; - LoadBehavior 0&#xff1a;此值表示插件已被禁用&#xff0c;将不会加载。 - LoadBehavior 1&#xff1a;此值表示插件将在 O…

015 Linux_生产消费模型

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;Linux &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多操作系统知识 文章目录 前言一、生产消费模型&#xff08;1&#xff09;概念引入&#xff08;2&#xff09;生产消费模型的优点…

键牌 6寸水口钳工业级电子斜嘴水口剪偏口钳子电工专用小斜口钳

品牌&#xff1a;键牌 型号&#xff1a;6寸水口钳灰红 材质&#xff1a;不锈钢 颜色分类&#xff1a;6寸水口钳灰红 多用途电工钳&#xff0c;高硬度&#xff0c;韧性好&#xff0c;材质优。 匠心之作&#xff0c;精工典范&#xff0c;不锈钢材质&#xff0c;加厚刀刃&am…

【JavaWeb】Spring非阻塞通信 - Spring Reactive之WebFlux的使用

【JavaWeb】Spring非阻塞通信 - Spring Reactive之WebFlux的使用 文章目录 【JavaWeb】Spring非阻塞通信 - Spring Reactive之WebFlux的使用参考资料一、初识WebFlux1、什么是函数式编程1&#xff09;面向对象编程思维 VS 函数式编程思维&#xff08;封装、继承和多态描述事物间…

Magical Combat VFX 2

我们为Unity推出的最新资产包:魔法战斗VFX包!这个包非常适合为你的游戏添加激烈而致命的魔法。有30多种独特的效果,包括血液、酸和毒咒,你可以在战斗场景中大显身手。而且移动支持和优化是首要任务,你可以在旅途中使用这些效果,而不用担心性能问题。使用功能齐全、移动就…

windows11安装SQL server数据库报错等待数据库引擎恢复句柄失败(二)

windows11安装SQL server数据库报错等待数据库引擎恢复句柄失败&#xff08;二&#xff09;&#xff0c;昨天在给网友远程的时候发现了一个新的问题。 计算机系统同样是Windows11&#xff0c;通过命令查出来的扇区相关结果也都是4096&#xff0c;但是最后的安装还是提示SQL ser…

JVM内存模型深度解读

JVM&#xff08;Java Virtual Machine&#xff0c;Java虚拟机&#xff09;对于Java开发者和运行 Java 应用程序而言至关重要。其重要性主要体现在跨平台性、内存管理和垃圾回收、性能优化、安全性和稳定性、故障排查与性能调优等方面。今天就下学习一下 JVM 的内存模型。 一、…

嵌入式学习40-数据结构

数据结构 1.定义 一组用来保存一种或者多种特定关系的 数据的集合&#xff08;组织和存储数据&#xff09; 程序的设计&#xff1a; …

31-Java前端控制器模式(Front Controller Pattern)

Java前端控制器模式 实现范例 前端控制器模式&#xff08;Front Controller Pattern&#xff09;是用来提供一个集中的请求处理机制&#xff0c;所有的请求都将由一个单一的处理程序处理该处理程序可以做认证/授权/记录日志&#xff0c;或者跟踪请求&#xff0c;然后把请求传给…