【51CTO外电头条】今天对于传统的数据库解决方案,我们面临着很多有关扩展性的问题,而 NoSQL 运动将这些问题的根源归罪于 SQL 查询语言。
我认为,如此多的人将 SQL 视为“万恶之源”的主要原因在于这样一个事实:查询语言通常被紧密地融入了数据库的部署之中。因此,当提到“NoSQL”时,我们本质上是在对非扩展的传统 RDBMS 部署说“不”(No)。
对于查询语言大量的替代方案,这一说法也是适用的。这些替代语言中的每一个都致力于解决传统 SQL 查询方案所欠缺的某一个方面,比如文档模型,或者提供一种更为简洁的方案,如键/值(Key/Value)程序。
曾与我交谈过的大多数人对于这个话题都相当困惑,并且往往交替地使用查询语言和结构。所以,我想通过本文抛砖引玉,希望能够为 NoSQL 环境中每个查询术语所表示的含义提供一个简单快捷的概述。之后,我还会试图通过讲解来消除某些常见的误解。
后 SQL 世界中常用的查询语法
以下为 NoSQL 语境中一些常用的查询语法。
键/值查询:正如字面含义,键/值查询应该是最为基本的查询格式。每个数据项关联一个唯一的标识符(键)。在 NoSQL 语境中,memcache 是这种接口最常用的部署方式之一。使用 memcache 执行一个复杂的查询时,最为常见的模式是将查询延迟至用作搜索引擎的底层数据库。这些查询的结果是一个键或一组键,然后利用这些键通过 memecache 数据存储来执行相应的值提取。这种方式在后 SQL 语境中获得了新的发展动力,原因在于它们自身能够相当自然地与分区和分发概念相融合,而分区和分发正是使得数据存储具有可扩展性的关键所在。换句话说,当人们别无选择时,他们愿意用大多数传统 RDBMS 所提供的强大的查询概念来交换可扩展性,即使只提供基本的查询支持。
基于文档的查询:文档查询这种模型的主要用途在于搜索引擎,在这中环境中最常见的是存储不同类型的温度,即使每个文档代表的是截然不同的对象。在 NoSQL 环境中,文档并不是我们在搜索引擎中见到的那种典型的 Word 或 PowerPoint 文件,而是 Jason 或 XML 形式的对象,或者关联一组键/值的二进制对象,比如 Cassandra。使用 SQL 术语来描述,文档可视为一个 blob(一种数据类型),关联着一组键,每一个键独立地进行索引并且维持着至该 blob 的引用。每个 blob 可以是不同的类型(表),每个 blob 可以具有不同的关联索引组(键)。通过关联索引来完成匹配工作。结果组通常包含多种类型,每个又包含不同的数据组。由于索引和 blob 无需与行和表的严格结构保持一致,所以将其称为“非结构的”(schemaless),也就是说,它可以具有同一类型的不同版本,并且向新的表中添加字段时无需修改任何表而且无需更新数据的旧版本。支持这种文档模型的数据库有 CouchDB 和 MongoDB。
模板查询:模板查询在 JavaSpaces 和 Hibernate 较新的版本中常常用到。利用基于模板的匹配,你可以根据类类型或遗传等级抓取一个对象,以及该对象的属性值。对于更为面向对象的模板匹配,你还可以根据图标(graph)属性中的特定项来执行匹配任务。在支持 JavaSpaces 模板查询模型的解决方案中,GigaSpaces 是较为知名的实现方式之一。
映射/化简(Map/Reduce):映射/化简通常用于执行分布式数据存储上的聚集查询。一个简单的例子,比如 Max 或 Sum。对于这种情况,查询全球需要在每个分区(映射)中独立的执行,然后进行聚集后返回客户端(化简)。隐式的映射/化简可以进行某个查询请求并隐式地传播该查询的执行。客户端获取聚集查询,就像它是一个单一查询。显式的模型运行用户执行自由格式(free-form)的代码,你可以控制映射模型(哪个调用指向哪些数据)、每个节点(即任务)中运行的代码以及结果。在一个常规的 Hadoop 部署中,映射/化简常常通过显式某些来进行。类似 Hive 和 Pig 的框架提供给了一个概要模型,可以隐式地处理进程。
SQL 查询:让我们思考一下,SQL 也算是另一种形式的动态语言,专门用于复杂的数据管理。使用 SQL,通常可在表和行中对数据进行排序。SQL 中的某些查询语法,比如 Join、分布式事务,以及为了获得扩展性而较常用的反模式语法。大体上来讲,正是 SQL 语法的这一点将 SQL 与有限的可扩展性关联起来了。支持 SQL 的 NoSQL 实现有使用 JPA 的 Google Bigtable、Hive/Hadoop、MongoDB 和 GigaSpaces。有关具体含义我将在下文进一步详述。
YeSQL:问题与 SQL 无关!
上文已经讲述了查询格式背后的某些概念,某个结论现在更为明朗了——过错的确与 SQL 无关。与许多语言一样,SQL 为你提供的是一根足够长的绳子,如果你喜欢,甚至可以那它来做悬梁自尽之用。几乎每种语言都是如此。如果想要将数据模型设计为与分布式模型相匹配,你会看到 SQL 在管理数据方面具有非常强大的功能。比如 Hive/Pig/Hbase 和谷歌的 JPA/Bigtable 就是很好的例子。对于这两种情况,底层的数据存储是基于可扩展的键/值存储,但前端查询语言刚好是基于 SQL 的。MongoDB 瞄准的也是类似的目标,主要的区别在于,这种数据库提供类似 SQL 的支持但并不完全遵守任何现有的标准。
请注意:事关架构!
诸如 Hive/HBase 以及 JPA/Bigtable 之类的 NoSQL 实现,可以视为很好的示例:下一代数据库如何同时支持线性扩展和 SQL API 接口。
关键之处在于将查询语法与底层数据存储剥离开来,如下图所示:
谷歌的 Bigtable 在 NoSQL 数据存储只是提供对 SQL API 的支持
融合正在发生
上周作者参加了 Hadoop summit 会议。Hadoop 提供的环境类似一个非常通用的培养基,这将为其带来一个生机勃勃的微生物系统。今天已经存在许多新的框架,它们在查询和处理方面对 Hadoop 数据管理方式进行了不同等级的萃取,比如 Hive、Cascading 和 Pig。许多框架提供的工具已经远远超出了 Hadoop 创建者最初的设想。
这让我想到一点:我们可以利用上文提到的分离模式,从而在与 SQl 的连接中提供对稳定模型的支持。也可以这样表述,我认为大多数数据库中领先者将支持所有上述语法,并且用户将不用只是因为某个数据库实现支持某种查询语言而选择它。
我们已经在动态语言上看到类似的趋势。以前,一门语言必须提供完整的工具、编译器、库和支持该语言的开发工具,这让选择某种语言成为一种重要的战略。而今天,Java 中的 JVM 或 .Net 中的 CLR 提供了相同的环境,能够支持更多的同一 JVM 运行时之上的动态语言。类似的例子,比如:Groovy 和 Java 或 Jruby。
***的话
在本文中我一直在讲,SQL 事实上是一个相当不错的查询语言并且将继续在后 SQL 世界中发挥重大的作用。不过,一家通吃的情况不会继续下去。数据管理的世界将建立在多种工具盒数据管理语言之上,每种语言或工具提供将某种特定的功能或服务。最为理想的情况,无论数据存储方式如何,我们应能够使用任何查询语言来访问任何数据。例如,我应能够使用文档模型来存储 JSON 对象,而且,无论任何时候,我都应能够使用 SQL 查询语法或简单的键/值 API 来查询这个 JSON 对象。
原文标题:YeSQL: An Overview of the Various Query Semantics in the Post Onl
【编辑推荐】