💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 一、概述 Hive 是将 SQL 转为 MapReduce。 **SparkSQL 可以理解成是将 SQL 解析成:“RDD + 优化” 再执行** ![](https://img.kancloud.cn/7b/7b/7b7bb5b60fb5eef7de8238f40d04e1ba_1302x705.png) 在学习 Spark SQL 前,需要了解数据分类。 **数据分类** 数据分为如下几类: | | 定义 | 特点 | 举例 | | --- | --- | --- | --- | | 结构化数据 | 有固定的 Schema | 有预定义的 Schema | 关系型数据库的表 | | 半结构化数据 | 没有固定的 Schema,但是有结构 | 没有固定的 Schema,有结构信息,数据一般是自描述的 | 指一些有结构的文件格式,例如 JSON | | 非结构化数据 | 没有固定 Schema,也没有结构 | 没有固定 Schema,也没有结构 | 指图片 / 音频之类的格式 | **总结:** * **RDD** 主要用于处理非结构化数据 、半结构化数据、结构化; * **Spark SQL** 是一个既支持 SQL 又支持命令式数据处理的工具; * **Spark SQL** 主要用于处理结构化数据 (较为规范的半结构化数据也可以处理)。 ### Spark SQL 数据抽象 #### DataFrame 和 DataSet Spark SQL 数据抽象可以分为两类: **① DataFrame**:DataFrame 是一种以 RDD 为基础的分布式数据集,类似于传统数据库的二维表格,带有 Schema 元信息 (可以理解为数据库的列名和类型)。DataFrame = RDD + 泛型 + SQL 的操作 + 优化 **② DataSet**:DataSet 是 DataFrame 的进一步发展,它比 RDD 保存了更多的描述信息,概念上等同于关系型数据库中的二维表,它保存了类型信息,是强类型的,提供了编译时类型检查。调用 Dataset 的方法先会生成逻辑计划,然后被 spark 的优化器进行优化,最终生成物理计划,然后提交到集群中运行!DataFrame = Dateset\[Row\] `RDD`、`DataFrame`、`DataSet`的关系如下: ![](https://img.kancloud.cn/87/bb/87bb58d9fa30f84f3273783c6c44f63e_1470x526.png) * **RDD\[Person\]**:以 Person 为类型参数,但不了解其内部结构。 * **DataFrame**:提供了详细的结构信息 schema 列的名称和类型。这样看起来就像一张表了。 * **DataSet\[Person\]**:不光有 schema 信息,还有类型信息。 #### 举例 假设 RDD 中的两行数据长这样: ``` RDD[Person]: ``` ![](https://img.kancloud.cn/3c/69/3c690c4a0f438babb7b2b7c59eea068b_371x143.png) 那么 DataFrame 中的数据长这样 ``` DataFrame = RDD[Person] - 泛型 + Schema + SQL 操作 + 优化 ``` ![](https://img.kancloud.cn/20/77/20778d4a7ac06c7fd076dd6f538271b6_715x212.png) 那么 Dataset 中的数据长这样: ``` Dataset[Person] = DataFrame + 泛型: ``` ![](https://img.kancloud.cn/e2/05/e205da7a941aae8b3eb61b6cf8685984_779x198.png) Dataset 也可能长这样: Dataset[Row]: ``` 即 DataFrame = DataSet[Row]: ``` ![](https://img.kancloud.cn/89/d9/89d9a887756ba67c95d3c24e33c18d09_354x202.png) **总结**: - DataFrame = RDD - 泛型 + Schema + SQL + 优化 - DataSet = DataFrame + 泛型 - DataSet = RDD + Schema + SQL + 优化 ## 二、SQLContext SparkSQL中所有相关功能的入口点是[SQLContext](http://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.SQLContext)类或者它的子类, 创建一个SQLContext的所有需要仅仅是一个SparkContext。 ```scala val sc: SparkContext // An existing SparkContext. val sqlContext = new org.apache.spark.sql.SQLContext(sc) // createSchemaRDD is used to implicitly convert an RDD to a SchemaRDD. import sqlContext.createSchemaRDD ``` **除了一个基本的SQLContext,你也能够创建一个HiveContext**,它支持基本SQLContext所支持功能的一个超集。它的额外的功能包括用更完整的HiveQL分析器写查询去访问HiveUDFs的能力、从Hive表读取数据的能力。用HiveContext你不需要一个已经存在的Hive开启,SQLContext可用的数据源对HiveContext也可用。HiveContext分开打包是为了避免在Spark构建时包含了所有的Hive依赖。如果对你的应用程序来说,这些依赖不存在问题,Spark 1.2推荐使用HiveContext。以后的稳定版本将专注于为SQLContext提供与HiveContext等价的功能。 用来解析查询语句的特定SQL变种语言可以通过`spark.sql.dialect`选项来选择。这个参数可以通过两种方式改变,一种方式是通过`setConf`方法设定,另一种方式是在SQL命令中通过`SET key=value`来设定。对于SQLContext,唯一可用的方言是“sql”,它是Spark SQL提供的一个简单的SQL解析器。在HiveContext中,虽然也支持"sql",但默认的方言是“hiveql”。**这是因为HiveQL解析器更完整。在很多用例中推荐使用“hiveql”。**