不要就这么放弃了 SQL

阅读数:5722 2014 年 5 月 8 日

SQL 这门语言已经稳定地发展了的 20 多年。同时,Java 客户端代码中冗长的 JDBC API 和 Java 语言缺乏一流的 SQL 支持的情况,使得 ORM 开发框架开始渐渐占据一席之地,例如后来作为标准加入到 JPA 和 Criteria API 中的 Hibernate。然而,出于性能上和表述上的考虑,一些用户还通过复杂的 SQL 查询语句和数据库进行交互 - 这种复杂性和 JPA 中所覆盖到的特性是相悖的。如果 SQL 和 JPA 越来越背离,我们的数据交互模式应该何去何从?

最近的 TopConf 2013 大会对我的影响

软件大会是我们行业在未来的 5 到 10 年将如何进展的新趋势和新思维的指向标。Topconf是一场在美丽的爱沙尼亚,塔林新举办的令人期待的大会,相当多的技术演讲都是关于大规模、分布式数据处理,以及新兴的技术和范例。第二天的开场主题演讲是由GridGain 公司的创始人和 CEONikita Ivanov所做的一场关于记忆体内运算方面的演讲。之后不久来自HazelcastChristoph Engelbert 举办了一个比赛演讲,不少的演讲都是关于异步编程和响应式编程,后者是一种新兴的范式,起源于 Scala 的 “subculture”,通过共用服务器上的可计算资源,来处理水平伸缩的情况。

无论何时,只要“垂直伸缩”和“水平伸缩”这样时髦的名词出现,一些广为人知的 NoSQL 制造者名字,比如MongoDB 或者ClouderaHadoop)也会跟随出现。这样的情况一直到 2013 年 5 月,MongoDB 被估值 1.2 亿。Nikita Ivanov 和 Christoph Engelbert 都提到了一个很好的观点,当我们在考虑伸缩问题的时候,这一观点将对我们的想法起到更真实和实际的影响。

垂直伸缩还是水平伸缩?集中化还是分布式?

首先,DRAM 的价格在过去几年飞速下跌,你都不敢想象十年前的记忆体内计算(那时候大概 1 美元 /MB),而现在很多公司有能力把他们所有的在线交易数据全放到内存中(大概 1 美元 /GB)。就像 Nikita 说的,99% 的公司都没有 9TB 大的在线数据量,这是在可支持的范围内的。这就允许把大量的数据从磁盘中(毫秒级别的访问)转移到内存中(纳秒级别的访问),而不用实际上改变软件架构!换句话来说,不需要使用什么新奇的技术,就可以使遗留系统得到量级的提速。这对正在从 COBOL 迁移至 Java,而又不太情愿替换关系数据库的大公司非常重要。再换句话来说,也许实际上我们并不需要新的数据存储范式。不是吗?

另一方面,数据量仍然在不断变得越来越大,而且人们想进行数据分片和数据分布式,物理上让数据更接近用户。即便是真的有这么一台可以计算的机器,可以迅速地处理越来越大的记忆体内计算,将巨大的数据通过网线传输,也会连续遇到网络延迟、包丢失和别的原因导致的性能问题等方面所造成的困扰。

Hazelcast 实施了一种“新的”范式,即把计算转向数据,而不是把数据转向计算。这也是 OLAP 数据库一直以来长时间在做的事情。现代的 RDBMS 融入基于 SQL 的语言,在接近数据的位置执行存储过程,这种语言很复杂而且很具有表述力。实际上,这甚至很像早期的共享主机系统,比如 IBM 7094,那时候开发者在中央计算引擎上分享时间槽。所以这并不是新的范式。我们只是在体验分布式和集中化计算的周期振荡,基于可用的资源和这些资源的力量。如果说 NoSQL 是分布式的强大力量,那么下降的 DRAM 价格就是集中化的强大力量。

同时,企业级 Java 中发生了什么?

这些主题是怎么关联到最近 Charles Humble 在 InfoQ 的调查,关于我们怎么在 Java 中访问关系数据库的呢?根据他和 Martin Fowler 的观察,通常,人们似乎对 ORM 变得越来越不满了。这些情感变化很大一部分是因为 ORM 会发生是一种泄漏的抽象(Leaky Abstractions)的这一事实。Joel Spolsky 很久之前就已经观察到了这一点

最近 JEE 7 中的 JPA 2.1 标准升级引入了一些的功能,可以更好地和“高级”的数据库特性进行集成,例如存储过程。关系数据库变得更符合 SQL 的标准,这个标准在不断地朝无法用 JPA 表述的方向发展。通过 ISO/IECSQL:1999 标准,我们可以利用分组集和(递归式的)通用表表达式。有了 SQL:2003 标准,我们已经有了非常复杂的开窗函数和 MERGE 语句。有了 SQL:2008 标准,我们可以执行分段的 JOIN 语句。通过 SQL:2011 标准,现在我们可以和临时数据库进行交互操作(现在 IBM DB2 和 Oracle 都已实现)。上述这些特色没有一个在 JPA 中或者别的大多数Charles Humble 所列举的 ORM 中有所体现,除了 jOOQ,这是 Java 建模 SQL 中一种类型安全的内部领域特定语言(在 Topconf 大会上也有相关主题的演讲)。

也就是说,当数据管理市场以快速的步伐扩大的时候,企业级 Java 社区还在慢慢地以小版本号的幅度更新着持久化 API。

未来会发生什么?

我们可以说的是,在未来几年软件技术会快速地变化。以下是一些将会被质疑的范式:

数据存储

RDBMS 已经很好地服务于我们,并且在将来继续很好地服务于我们。它们的创建基于很复杂的和很可靠的理论——关系理论,这种模型能够适用于许多问题的解决。

其它的类型的数据存储则会继续浮现,在非 RDBMS 市场中争夺新的优势。关于为什么应该选择别的数据存储而不是调整现有的,有两个基本的原因:

  • 对于高度层次型的或者非结构化的数据,关系数据模型不够用。
  • ACID 不能满足极端的水平伸缩情况,网络潜在问题导致在分布式系统中所有的 A-C-I-D 都变成难以解决的问题。

但是,当说到集成列存储(也被称为 NewSQL),更多的像是让老象学习新技能,关系型数据库制造者最终也会集成经过验证的 NoSQL 功能。

语言

命令式(和面向对象)编程在最近几年,已经受到函数式编程极大的挑战。显著的挑战者有 Scacla,Javascript,C# 3.0,VB 9 和 Java 8。一个简单的解释是,函数式编程让计算逻辑更加容易地接近数据。同时,产生的副作用是期望中的,这也被 Simon Peyton Jones 自己确认,当时他在和 LINQ 的创造者 Erik Meijer讨论编程语言的未来

另一方面,Erik Meijer 创造的 LINQ 的人气,已经证明声明式查询语言是复杂的数据库交互的一种好范式。SQL 本身在之前提到的多样的新标准上不断提升。眼下,Facebook 已经开源了他们自己的ANSI-SQL,它是建立在 Apache Hadoop 之上的,基于自己编写的查询语言。

可以说的是,这些语言范式中没有一个可以被别的所替代。

SQL 无所不在

在数据处理上 SQL 无所不在,这让我们更加了解到为什么 Charles Humble 发现,在使用类似 Hibernate 这样传统的 ORM 时,会让人越来越不爽的重要原因。这些工具已经解决了以下两个问题:

  • CRUD 的重复性
  • 缓存,可以提高磁盘访问速度。

智能缓存是很困难的,即便是实现了很多实体级别的 SQL 缓存功能的 Hibernate。Hibernate 或者 JPA 的缓存机制之所以能够现实,是因为 ORM 策略已经深深地和 JPQL 集成。由于缺乏原生查询功能,很难绕过缓存的核心机制。

但是别忘了内存变得多么的便宜?缓存大多数数据可以保证很少量地访问磁盘。如果数据不再从磁盘上访问(毫秒级),而是从内存中访问(纳秒级)会怎么样?当数据库已经把所有相关的数据缓存到内存中,我们依然需要完整的和复杂的二级缓存吗?

数据库不仅有能力把在线交易数据一直放在内存中,而且它们早就可以实现一些复杂的缓存机制了。想想 Oracle 的游标缓存查询结果缓存,和标量子查询缓存吧。

虽然 JPA 依然是 CRUD 操作的优秀工具,但以 SQL 为中心的工具正在被越来越多的人选择使用,比如:MyBatis 或者 jOOQ(都是“后 JPA 框架”)表明了一种需要再次更加接近 SQL 的确定需求。ANSI-SQL 标准不断发展,把不断革新的数据库的各种功能进行标准化,比如:Oracle,SQL Server,PostgreSQL,通常是那些很难集成到 JCP 甚至是今后的 JPA 版本中的一些特性。JPA 2.1 支持存储过程,但是在客户端代码管理的这些支持,看起来和在 JDBC 中实现的可调用语句(CallableStatements)一样单调乏味。另外,JPA 2.1 虽然有了各种新的与存储过程相关的注解,但并没有把嵌入式的用户自定义函数加入到 SQL 语句中,而这些却被不知名的 CriteriaQuery API 不充分的表述出来。大会上的所有关于 jOOQ 演讲,我都在问观众他们使用 CriteriaQuery 幸福吗。他们的回答是一致的不幸福。

总结

时光的列车辙辗而过。RDBMS 仍旧在不断发展和拥抱新的功能,按照 ANSI SQL 进行自我标准化,并逐渐放弃 JPA 2.x。在这几次变化中,JPA 规范看起来局限了数据存储市场进行的革新。EclipseLink 最近通过 JPA 扩展支持 MongoDB,表明了标准制定者并不确定他们将走向何方。

但是有一件事情是确定的。我们不会这么快放弃 SQL。那么为什么不再次拥抱它?

查看英文原文:Don’t jump the SQL ship just yet

译者信息

石岩(帐号:Shi Yan) 微博:@hlcfan


感谢邵思华对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

收藏

评论

微博

发表评论

注册/登录 InfoQ 发表评论