作者:Guilhem Bichot 译:徐轶韬

在MySQL 8.0.14中,添加了LATERAL派生表的功能。在线手册https://dev.mysql.com/doc/refman/8.0/en/lateral-derived-tables.html中描述了语法,并提供了如何使用该功能在表中查找最大值的示例。

在本文中,我将利用LATERAL解决另一个问题:假设我们有一堆节点,并希将每个节点与其他节点连接生成一个“随机图”。

我们从一个nodes表开始:

create table nodes(id int);

这个表将填充20个节点,使用递归通用表表达式Common Table Expression(MySQL 8.0.1的 另一个功能):

insert into nodeswith recursive cte(n) as(select 1union allselect n+1 from cte where n<20)select * from cte;

现在,让我们在图上创建随机的边。它们是有方向的(具有“from”和“to”)。

create table edges (from_id int, to_id int);

对于每个原始节点,让我们选择两个随机目标节点,并将它们连接到原始节点。

如果我们使用普通派生表来存储两个目标节点:

insert into edges(from_id, to_id)select origin_nodes.id, target_nodes.idfrom nodes as origin_nodes,(select idfrom nodesorder by rand()limit 2) as target_nodes;

在执行INSERT查询时,此派生表仅计算(实体化)一次且仅有一次。在伪代码中,这样描述:

select two random target nodes, store into target_nodesfor each row R in origin_nodes:join R with target_nodesinsert the result into edges

因此,所有节点都只会连接到在开始时选择的相同的两个目标节点:

这不是理想的结果;所以删除掉:delete from edges;

在抛弃先前的SELECT查询之前,让我们注意它的EXPLAIN执行计划:

为了解决我们的问题,我们需要为每个原始节点重新计算目标节点,比如这个伪代码:

for each row R in origin_nodes:select two random target nodes, store into target_nodesjoin R with target_nodesinsert the result into edges

为了实现这一点,我们需要告诉MySQL两个随机目标节点的选择取决于当前的原始节点,每次都重复,我们使目标节点人为地依赖于原始节点:

insert into edges(from_id, to_id)select origin_nodes.id, target_nodes.idfrom nodes as origin_nodes,(select idfrom nodesorder by rand()+0*origin_nodes.idlimit 2) as target_nodes;

0 * origin_nodes.id不会更改ORDER BY子句的值,但是,它使这个子句以及由此派生的表target_nodes依赖于origin_nodes的当前行。

但是普通的派生表不允许依赖于FROM子句的先前表,所以当我们运行上面的查询时,我们会得到:ERROR 1054 (42S22): Unknown column 'origin_nodes.id' in 'order clause'

所以我们使它成为一个LATERAL派生表,根据定义它是:允许依赖于FROM子句的先前表的派生表。

insert into edges(from_id, to_id)select origin_nodes.id, target_nodes.idfrom nodes as origin_nodes,LATERAL (select idfrom nodesorder by rand()+0*origin_nodes.idlimit 2) as target_nodes;

现在它按照我们的预期工作,目标节点产生了变化:

并且EXPLAIN显示:

请注意新的指示内容:-DEPENDENT DERIVED:派生表依赖于另一个表;-origin_nodes上面Rematerialize:我们每次读取的行origin_nodes,MySQL从新实体化派生表Derived2(这是派生表target_nodes在MySQL的内部名称)。

让我们的问题变得更复杂一些:到目前为止,我们将每个原始节点连接到两个随机目标节点;如果我想要目标节点的数量也是随机的呢?比方说,将每个节点连接到0到4之间的多个随机节点?

查看我们之前成功的查询:

insert into edges(from_id, to_id)select origin_nodes.id, target_nodes.idfrom nodes as origin_nodes,lateral (select idfrom nodesorder by rand()+0*origin_nodes.idlimit 2) as target_nodes;

我们现在必须使LIMIT 2中的“2”成为0到4之间的随机值。由于LIMIT不允许变化,所以我们将放弃使用LIMIT并稍微变化。要构建0到4目标节点,我们将

选择所有节点作为目标,

按随机顺序编号(使用ROW_NUMBER窗口函数),

将row_number与0到4之间的随机最大值进行比较,可以使用WHERE子句根据row_number对它们进行过滤。

delete from edges;insert into edges(from_id, to_id)select origin_nodes.id, target_nodes.idfrom nodes as origin_nodes,lateral (select id,row_number() over (order by rand()+0*origin_nodes.id) as rnfrom nodeslimit 4) as target_nodeswhere target_nodes.rn

如您所见,对于id为1的输入节点,我们有三个目标节点(id 2,4,8),对于输入节点2,我们有一个(id 20),对于3我们有一个,对于4我们有两个,...根据需要,每个原始节点具有不同数量的目标节点。

总结一下,在MySQL中我们现在有了LATERAL,所以每当你想到“每一行让我们这样做”时,你可以找到一个带有LATERAL派生表的解决方案。

我希望你会发现这个功能很有用。感谢您使用MySQL!

mysql lateral_MySQL 8.0.14的LATERAL派生表相关推荐

  1. 【mysql】 踩坑记录之derived(派生表)

    文章目录 前言 出现的问题 如何解决 方法一:改写sql 方法二:改写sql 方法三:改写sql 前言 很多时候我们常常感觉到,不要你以为,mysql要它以为.记录派生表踩坑记录. 首先说明环境mys ...

  2. MySQL 8.0 新特性之横向(LATERAL)派生表

    文章目录 我在慕课网发布的免费视频讲解 MySQL 8.0 版本新特性. MySQL 将FROM中的子查询称为派生表(Derived Table).以下查询使用了一个派生表: SELECT * FRO ...

  3. MySQL 8.0-13.2.11.9 Lateral Derived Tables(横向派生表)

    A derived table cannot normally refer to (depend on) columns of preceding tables in the same FROM cl ...

  4. LATERAL横向派生表

    参考董旭阳TonyDong的博客,网址:https://blog.csdn.net/horses/article/details/86510905 lateral 横向的 mysql数据库从8.0支持 ...

  5. mysql-8.0.14zip怎么使用_mysql 8.0.14 安装配置方法图文教程(通用)

    mysql服务8.0.14安装(通用),供大家参考,具体内容如下 安装环境:windows 安装步骤: 1.下载zip安装包 2.解压zip安装包 3.配置环境变量 4.添加配置文件 5.cmd安装m ...

  6. mysql-8.0.14图文安装_mysql8.0.14安装配置方法图文教程(通用)

    mysql服务8.0.14安装(通用),供大家参考,具体内容如下 安装环境:windows 安装步骤: 1.下载zip安装包 2.解压zip安装包 3.配置环境变量 4.添加配置文件 5.cmd安装m ...

  7. 手机开启apache_微信否认“年终奖人均280万”;MySQL 8.0.14 稳定版发布;支付宝集五福昨开启,一天29万人集齐......

    IT服务圈儿 有温度.有态度的IT自媒体平台  开发者头条  1.MySQL 8.0.14 稳定版发布 MySQL 8 已于1月21日发布了 8.0.14 更新版本(GA)! 下载地址 Windows ...

  8. mysql优化案例(14秒优化到不到1秒)

    优化案例 前面用过的tbiguser表有10000000条记录 创建tuser1表和tuser2表,并初始化若干的数据. create table tuser1( id int primary key ...

  9. 利用MySQL Cluster 7.0 + LVS 搭建高可用环境

    1.前言 随着数据量规模的扩大,企业对 MySQL 的要求就不仅仅是能用了,也在寻求各种高可用方案.以前我们的大部分高可用方案其实还存在一定缺陷,例如 MySQL Replication 方案,Mas ...

最新文章

  1. 南瓜派php,南瓜派_【顶级厨师】南瓜派_日志_美食天下
  2. vue暴露的全局方法_Vue中实现全局方法
  3. probuffer java_Protocol Buffer的使用
  4. php显示doc文件乱码,如何解决php doc 乱码问题
  5. 简述container与container-fluid的区别
  6. linux模拟进程调度,Linux进程调度模拟3
  7. 怎么用计算机 在名字中间打一个点,外国人名字中间的点怎么打 外国人的名字中间有...
  8. 软件工程 毕业论文 文献引用 中英文文献整合
  9. wincc控件包下载_Simatic HMI WinCC V7.4 SP1 组态软件下载
  10. 祝贺父亲节快乐的python代码_2019祝爸爸父亲节快乐的最新父亲节祝福说说句子大全...
  11. windows server 2016云主机如何挂载云硬盘
  12. 智慧水务大数据平台-智慧水务建设方案
  13. HDU6608 Fansblog
  14. Java 多线程的应用场景
  15. 【PyTorch】PyTorch神经网络实战入门
  16. Codevs 1009 产生数
  17. 定制开发体育指数直播APP体育指数数据API调用代码
  18. Zabbix监控系统开发(2):JSON多维数组筛选字段是否包含字符串的解决方案
  19. 汉诺塔递归的空间复杂度_暴力递归与动态规划 1.0
  20. 关闭apache服务器banner

热门文章

  1. 论文笔记_2018_IEEE Access_评估地图用于车辆定位能力的因素
  2. 4月17日鸿蒙开发者大会,鸿蒙真的要来了?华为开发者大会
  3. 终止代码 PAGE_FAULT_IN_NONPAGED AREA蓝屏解决办法<VM虚拟机>
  4. std::atomic原子操作
  5. maven自定义目录
  6. 数组a[],a,a之间的区别
  7. 一个多数程序员都会犯的错:Java方法传参的问题
  8. 牛客寒假基础集训营 | Day1 E题—rin和快速迭代
  9. 爆笑视屏,看看外国人的创意,搞笑视屏不是只有假唱做做
  10. 职场中公文、PPT和业务文案如何写