Spark SQL 本机语法和 Spark 中的 Hive QL 语法有什么区别?

问题描述

在 Spark 官方文档中,提到了两种 sql 语法:Spark 原生 sql 语法和 Hive QL 语法。我找不到有关它们差异的详细说明。我对以下问题感到困惑:

  1. Spark 原生 sql 语法是 Hive QL 的子集吗?我问它是因为在一些文章中他们是这样说的。而且根据 Spark 官方页面 https://spark.apache.org/docs/3.0.0-preview2/sql-migration-guide.html#compatibility-with-apache-hive 中的解释,Spark sql 似乎并不支持 Hive QL 的所有功能
  2. 如果问题 1 是肯定的,为什么我可以在 Spark sql 中运行“join A rlike B”但不能在 Hive 中运行?
  3. Spark 如何将 sql 语句视为 Spark 原生 sql 或 Hive QL?
  4. 当我们在 Spark Session 初始化期间使用 enableHiveSupport 时,是否意味着 Spark 会将所有给定的 sql 语句视为 Hive QL?

解决方法

序言

HiveQL 是 SQL-92、MySQL 和 Oracle 的混合体 SQL 方言。它还提供了来自后来的 SQL 标准的特性,例如窗口函数。此外,HiveQL 扩展了一些不属于 SQL 标准的功能。它们受到 MapReduce 的启发,例如多表插入。
简而言之,您可以通过类似 SQL 的 HiveQL 使用 MapReduce 基于 Java 的强大功能分析数据,因为 Apache Hive 是一种基于 Hadoop 的数据仓库。

使用 Spark SQL,您可以读取和写入各种结构化格式的数据,其中之一是 Hive 表。 Spark SQL 支持符合 ANSI SQL:2003 的命令和 HiveQL。简而言之,您可以通过类似 SQL 的 Spark SQL 使用 Spark 引擎的强大功能来操作数据,Spark SQL 涵盖了 HiveQL 的大部分功能。

使用 Hive 时,您必须使用 Hive 支持实例化 SparkSession,包括连接到持久性 Hive 元存储、支持 Hive serdes 和 Hive 用户定义函数。
没有现有 Hive 部署的用户仍然可以启用 Hive 支持。 Spark 为您处理存储。

val spark = SparkSession
  .builder()
  .appName("Spark Hive Example")
  .config("spark.sql.warehouse.dir",warehouseLocation)
  .enableHiveSupport()
  .getOrCreate()

答案

  1. 我想说它们高度重叠。 Spark SQL 几乎是 HiveQL 的超集
  2. Spar SQL 不是 HiveQL 的子集;关于后半部分,是因为在 SQL:2003 标准中引入了正则表达式之类的谓词。 Spark SQL 符合 SQL:2003,HiveQL 仅实现了 SQL:2003 中引入的极少数功能,在少数功能中,rlike 未包含在 HiveQL 中。
  3. 您必须查看 Spark 的 source code。实际上,在我看来,只需要记住 Spark SQL 可以帮助您从各种数据源读取和写入数据,并且它涵盖了 HiveQL。 Spark SQL 具有 HiveQL 的大部分功能。
  4. 不完全是。 Spark SQL 就是 Spark SQL。启用您提到的功能后,通常意味着您将与 Apache Hive 进行通信。即使您没有 Apache Hive 的实体,启用该功能后,您也可以通过 Spark SQL 使用 HiveQL 的某些功能,因为 Spark SQL 支持 HiveQL 的大多数功能,并且 Spark 有一个内部机制来处理数据仓库的存储。
/* Example of Utilizing HiveQL via Spark SQL */
CREATE TABLE person (id INT,name STRING,age INT,class INT,address STRING);
INSERT INTO person VALUES
    (100,'John',30,1,'Street 1'),(200,'Mary',NULL,'Street 2'),(300,'Mike',80,3,'Street 3'),(400,'Dan',50,4,'Street 4');

/* Utilize a feature from HiveQL */
SELECT * FROM person
    LATERAL VIEW EXPLODE(ARRAY(30,60)) tabelName AS c_age
    LATERAL VIEW EXPLODE(ARRAY(40,80)) AS d_age;

参考文献

  1. Damji,J.、Wenig,B.、Das,T. 和 Lee,D.,2020 年。学习 Spark:闪电般的数据分析。第二版。加利福尼亚州塞瓦斯托波尔:O'Reilly,第 83-112 页。
  2. ISO/IEC JTC 1/SC 32 数据管理和交换,1992,信息技术 - 数据库语言 - SQL,ISO/IEC 9075:1992,美国
  3. ISO/IEC JTC 1/SC 32 数据管理和交换,2003,信息技术 — 数据库语言 — SQL — 第 2 部分:基础 (SQL/Foundation),ISO/IEC 9075-2: 2003年,美国
  4. 怀特,T.(2015 年)。 Hadoop:权威指南。第四版。 Sebastopol,O'Reilly Media,第 471-518 页。
  5. cwiki.apache.org。 2013. LanguageManual 横向视图。 [在线] 可在:https://cwiki.apache.org/confluence/display/Hive/LanguageManual 获得。
  6. spark.apache.org。 2021. 蜂巢表。 [在线] 可在:https://spark.apache.org/docs/latest/sql-data-sources-hive-tables.html 获得。