公用表达式:
mysql 8 支持公用表达式,包括非递归和递归。
CTE作用:
同一查询中,两次引入派生表是不可以的。因为查询会根据派生表的引用次数,计算两次或者多次,这会引发非常严重的性能问题。CTE,就是让子查询只会计算一次的存在。
非递归CTE
派生表 ,即子查询完全相同,mysql也会执行两遍,但是cte 只需要执行一次;
而且cte可以引用其他CTE,派生查询不能引入其他派生查询;
with cte1 as (select *** from ***),
cte2 as (select **** from cte1)
select ** from cte1,cte2..
递归CTE
一种特殊的cte。
with resursive cte as //必须以with resursive开头
select *** from *** // 这块是子查询 SEED
union all // 使用union all 或者 union distinct 分隔
select *** from cte,table_name // recursive 查询部分
生成列:
生成列 :根据列定义中的包含的表达式,计算得出的
virtual 虚拟生成列:从表中读取记录时,将计算该列;
stored 生成列:向表中写入数据时,计算并存储在表中;
操作方式:
新建的时候:
full_name varchar(20 )as (concat (firstname,' ' ,lastname));
修改现有表:
alter table tablename
add full_name as (concat (firstname,' ' ,lastname)) virtual;
insert
生成列不允许指定值,如果INSERT语句包含生成列,请指定为 DEFAULT
索引:
生成列索引,其实就类似ORACLE的函数索引。
首先,如果where子句是函数,那么这个列肯定不能被使用索引的。
创建一个虚拟列,并加上索引。
例如:
alter table employee
ADD hire_date_year year(4) as (year(hire_date)) virtual,
ADD index (hire_date_year);
使用生成列为JSON建立索引
JSON上不能直接建立索引,因此如果要在json列上使用索引,可以使用虚拟列和在虚拟列上创建的索引来提取信息。
以json列 内容中有 city 为例,添加一个虚拟列和索引
alter table tablename
add column city varchar(20) as ( json列->>'$.address.city'),
add index (city);
可以参考文档,了解更多内容:
https://dev.mysql.com/doc/refman/8.0/en/create-table-generated-columns.html





