前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SQL的巨大飞跃:MySQL 8.0发布

SQL的巨大飞跃:MySQL 8.0发布

作者头像
IT派
发布2018-07-30 14:22:45
1.2K0
发布2018-07-30 14:22:45
举报
文章被收录于专栏:IT派

“你仍在使用SQL-92吗?”是我在“新SQL”演讲中的开篇问题。在我提出这个问题后,竟然有大部分观众坦承仍在使用25年前的技术。而如果我问谁还在使用Windows 3.1,这个版本也是在1992年发布的,则只有少数人举手......而且他们显然在开玩笑。

显然,这种比较不算公平。但它至少表明,围绕较新的SQL标准的技术推广相当缺乏。自SQL-92以来,实际上有五次更新 - 许多开发人员却从未听说过它们。最新版本是SQL:2016。

因此,许多开发人员并不知道自1999年以来,SQL已经不再局限于关系代数或关系模型。SQL:1999引入了在关系代数(横向递归的)没有的运算和打破了第一范式传统解释的类型(arrays!)。

从那时起,19年来,SQL功能是否符合关系思想已不再重要。重要的是,一个功能具有定义明确的语义并解决一个真正的问题。学术方法已经让位于实用的方法。如今SQL标准为几乎所有的数据处理问题提供了一个实用的解决方案。其中一些留在关系域内,而另一些则没有。

注意

在说SQL数据库时不要说关系数据库。SQL实际上不仅仅是关系。

很多开发人员仍然以25年前使用SQL的方式使用SQL,这实在太糟糕了。我认为主要原因是开发人员缺乏知识和兴趣,以及数据库产品对新SQL的支持不足。

我们来看看MySQL的支持程度。考虑到它的市场份额,我认为MySQL对新SQL的轻视极大程度上导致了这种不幸的情况。我曾在2013年的博客文章“MySQL对SQL的影响正如MongoDB对NoSQL一样糟”中谈到了这个观点。信息的关键是“MongoDB是受欢迎的,但它的在同类中不具备大的代表价值,就像MySQL一样”。Joe Celko以不同的方式表达了他对MySQL的看法:“ MySQL不是SQL,它只是从SQL中借用关键字 ”。

你可以在YouTube上的MySQL WAT演讲中看到一些存在问题的SQL解释示例。请注意,该视频是2012年的,使用MySQL 5.5(当时的GA版本)。在那以后,MySQL 5.6和5.7出来了,这大大改善了这种情况。新的安装系统的默认设置现在好多了。

他们真的在考虑如何减轻更改默认值的影响,这一点特别好。例如,当ONLY_FULL_GROUP_BY默认启用时,他们花费更多的时间来实现主要SQL数据库之间最完整的功能依赖性检查:

大约在MySQL 5.7发布的同时,我停止了对MySQL的攻击。当然,我在开玩笑。偶尔我还在抨击MySQL ......但从那时起这种抨击就不太容易了。

顺便说一下,你知道MySQL仍然不支持check约束吗?就像在以前的版本中一样,你可以在create table声明中使用check约束,但它们会被忽略。是的没错——没有警告就直接被忽略。连MariaDB都在一年前解决了这个问题。

呃,我又在抨击了!抱歉——老习惯很难改变。

尽管如此,在过去的几个版本中,MySQL的开发理念已经发生了明显的变化。发生了什么?你已经知道答案了:自从Oracle通过Sun收购了MySQL后,MySQL正处于新的管理之下。我必须承认:在过去的10年中,这可能是SQL发生的最好的事情,而我就是指SQL而不是MySQL。

我认为单个数据库版本会对整个SQL生态系统产生巨大影响的原因很简单:MySQL是链中最薄弱的一环。如果你强化了这一环,整条链变得更加强大。让我详细说明一下。

MySQL非常受欢迎。据db-engines.com称,它是第二流行的SQL数据库。更重要的是:它是最受欢迎的免费 SQL数据库。这对任何必须使用多个特定SQL数据库的人都有很大的影响。这些通常是制造内容管理系统(CRM),电子商务软件或对象关系映射器(ORM)等产品的软件供应商。由于其广受欢迎,这些厂商通常需要支持MySQL。其中只有少数人咬紧牙关,真正支持多数据库——Java Object Oriented Querying(jOOQ)在这方面确实很突出。许多供应商只限于常规支持的SQL语言中,即MySQL。

受MySQL影响的另一个重要群体是学习SQL的人。他们可以合理地认为最流行的免费SQL数据库是学习的良好基础。他们不知道的是,MySQL将SQL-foo限制为诸多SQL语言中最弱的SQL语言。基于Joe Celko的声明:这些人知道关键字,但不明白它们的真正含义。更糟的是,他们还完全没有听说过现代SQL特性。

上周,当Oracle终于发布了一个普遍可用的版本MySQL 8.0时,这一切都发生了变化。这是一个具有里程碑意义的版本,因为MySQL最终超越了SQL-92以及纯粹的关系教条。在其他一些标准的SQL功能中,MySQL现在支持窗口函数(over)和公用表表达式(with)。毫无疑问,这是两个最重要的Post-SQL-92功能。

软件供应商宣称由于MySQL不支持所以这些功能无法使用的日子已即将过去。如今最流行的免费SQL数据库的文档中也已经包含了窗口函数和公用表表达式。让我大胆地声称:MySQL 8.0是数据库前进的一小步,是SQL进步的一大步。

一切正在变得更好,未来是光明的!由于MySQL已经由Oracle掌握,MySQL的前团队(其中有最初的创建者)创建了MySQL分支MariaDB。显然,他们的策略是增加许多新功能来说服MySQL用户考虑他们的竞争产品。就个人而言,我认为他们会牺牲质量——就像以前的MySQL一样——但这是另一回事。在这里,MariaDB已经使check约束有效达一年之久了,这才是更实质性的。这就产生了一个问题:MySQL还能继续忽略check约束多久?或换句话说,他们还能忍受我的抨击多久;)

除了check约束之外,MariaDB 10.2还引入了窗口函数和通用表表达式(CTE)。那时候,MySQL有一个CTE测试版,但没有窗口功能。MariaDB正在迅速改进。

在10.3中,MariaDB被设置为发布“系统版本化表”。简而言之:一旦激活表格,系统版本控制就会保留更新和删除行的旧版本。默认情况下,查询将像往常一样返回当前版本,但可以使用特殊的语法(as of)来获取旧版本。你可以在MariaDB的公告中阅读更多关于此的信息。

SQL标准中在2011年引入了系统版本管理。现在看来,MariaDB将成为第一个支持它的免费SQL数据库。我希望这是对其他供应商的激励——对于要求供应商支持更新的SQL功能的用户也是如此!

既然新SQL的采用最终得到了一些支持,只剩下一个问题:细致的细节。标准定义的功能有很多子功能,并且由于其数量庞大,通常只支持其中一部分。这意味着仅仅说数据库支持窗口函数是不够的。它实际上支持哪种窗口函数?其中以什么为单位?(行,排列还是组?)这些问题的答案区分了营销噱头和真正强大的功能。

为了让开发人员能够更方便地使用新SQL,我正在测试这些细节,以便突出产品之间的差异。这些测试的结果用和上面一样的表格来展示。本文的其余部分将简要介绍MySQL 8.0中引入的新标准SQL功能,并讨论一些实现上的差异。如你所见,MySQL 8.0在这方面非常好。值得注意的例外是它的JSON功能。

窗函数

SQL分为有窗函数之前的SQL和有窗函数之后的SQL。可以毫不夸张地说,窗函数改变了一切。一旦你理解了窗函数,你就无法想象如果没有它们,你将如何生活。最常见的用法有例如每组找到最好的N行,构建运行总数或移动平均值,以及对连续事件进行分组,只是冰山一角。窗函数是避免自连接的最重要的工具之一。仅此就可以使查询不那么冗余,速度也更快。窗函数非常强大,即使是一些新事物诸如Apache SQL实现(Hive,Impala,Spark),NuoDB和Google BigQuery多年前就引入他们了。所以说MySQL加入得实在是很晚。

下面的表格显示了over从句对某些主要SQL数据库的支持。如你所见,正如PostgreSQL在其新主页上声称的那样,MySQL的实现实际上超过了“世界上最先进的开源关系数据库”的功能。但是,PostgreSQL 11将重新夺回这一领域的领导者地位。

MySQL 8.0提供的实际窗口函数集也非常接近现有技术水平:

通用表表达式(with [recursive])

MySQL 8.0的下一个主要增强功能是通用表表达式或者说with [recursive]从句。重要的用例是使用单个查询遍历图,生成任意数量的行,将CSV字符串转换为行(反转listagg/ group_concat)或是识字SQL。

MySQL的第一次实现再一次缩小了差距。

其他标准SQL功能

除了窗口函数和with从句外,MySQL 8.0还引入了一些其他标准SQL功能。但与前两者相比,这绝不是杀手锏。

正如你所看到的,Oracle推动SQL标准对JSON的支持。Oracle数据库和MySQL目前是这方面的领导者(两者都来自同一个供应商!)。json_objectagg和json_arrayagg功能甚至在MySQL 5.7.22得到兼容。但是,值得注意的是,MySQL不遵循这两个函数的标准语法。标准中定义的修饰符(例如order by子句)通常不受支持。Json_objectagg既不识别关键字key和value也不接受冒号(:)来分隔属性名称和值。看起来像是MySQL将它们解析为常规函数调用——而不是标准描述的语法。

同样有趣的是,与Oracle数据库(它们不默认为absent on null)一样,json_arrayagg似乎在处理null值时出错了。在两个据称无关的产品中看到同样的问题总是很有趣。再加上这两个产品来自同一个供应商的事实又增加了一个转折点。

列表中的最后两个功能,grouping函数(与rollup相关)和from从句的列名是解决特定的问题的方法。他们的MySQL 8.0实现基本上与其他数据库一致。

此外,MySQL 8.0还引入了标准的SQL角色。以上表格未列出的原因很简单:表格是基于我对所有这些数据库运行的实际测试。我自行开发的测试框架还不支持需要多个用户的测试用例——目前所有测试都使用默认用户运行,所以我无法测试访问权限。但是我会逐步改善的,请继续关注。

其他显著的增强功能

我想用MySQL 8.0修补程序和与SQL标准无关的改进来结束本文。

其中之一是关于在索引声明中使用desc修饰符:

大多数(如果不是全部的话)数据库在索引创建中使用与order by从句相同的逻辑,即默认情况下,列值的顺序是升序。有时需要按照相反的方向对一些索引列进行排序。这时需要在索引中指定desc。以下是MySQL 5.7文档对此的看法:

index_col_name规格可以以ASC或DESC结束。这些关键字可用于将来的扩展,用于指定索引值存储的升序或降序。目前,他们会通过语法分析但同时会被忽略 ; 索引值始终以升序存储。

“他们会通过语法分析但同时会被忽略”?更具体地说:他们会通过语法分析,但就像上文提及的check约束一样不经警告而被忽略。

但是,这已经在MySQL 8.0中解决了。现在有一个警告。只是玩笑!Desc现在仍很特殊。

MySQL 8.0还有许多其他的改进。请参阅“ MySQL 8.0中的新增功能 ”。其他可查阅文章:

  • 直方图(优化器统计)(https://dev.mysql.com/doc/refman/8.0/en/analyze-table.html)
  • InnoDB中的数据字典(另请参见MyISAM的结尾)(https://mysqlserverteam.com/atomic-ddl-in-mysql-8-0/)
  • 隐性索引(https://mysqlserverteam.com/mysql-8-0-invisible-indexes/)
  • 改进后的默认值(不再有latin1_swedish_ci了!)(https://mysqlserverteam.com/new-defaults-in-mysql-8-0/)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT派 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 窗函数
  • 通用表表达式(with [recursive])
  • 其他标准SQL功能
  • 其他显著的增强功能
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档