Spark系列 - 5 - Saprk SQL

Spark SQL 是一种即支持SQL又支持命令式数据处理的工具,主要用于处理结构化和半结构化数据,整合SQL查询和Spark编程,通过相同的标准的连接方式连接不同的数据源,同时兼容Hive。其通过对数据的抽象实现对数据的分析处理。包括 DataFrame 和 DataSet 两种,下面详细介绍这两种抽象数据集。

一、DataFrame

以RDD为基础的分布式数据集,类似传统数据库的二维表,带有schema信息。在Spark程序中如果想使用简单的SQL接口对数据进行分析,首先需要将数据源转换成DataFrame对象,进而在对象上调用各种API实现需求。

1、创建DataFrame

可以从内存中读取数据,也可以同文件中读取数据,这里演示从文件中获取。

1.1 定义一个Json的数据文件

user.json内容如下:

{"name": "zhangsan", "age": 25}
{"name": "lisi", "age": 30}
{"name": "wangwu", "age": 25}

1.2 创建环境对象

import org.apache.spark.sql.{DataFrame, SparkSession}

val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("SparkSQLDemo")
val spark: SparkSession = SparkSession.builder().config(conf).getOrCreate()

1.3 读取json文件获取数据

val dataFrame: DataFrame = spark.read.json("/data/user.json")
dataFrame.show()

2、DataFrame基础操作

DataFrome自带了一些对象方法,如select、where、count、filter等。

2.1 查询schema信息

dataFrame.printSchema()

2.2 列选

dataFrame.select("name").show()

2.3 行选

查询年龄大于25的用户

这里需要引入一个隐式转换 import spark.implicits._

dataFrame.select('name, 'age).where('age>25).show()

2.4 添加列

dataFrame.withColumn("gender", lit("")).show()

2.5 修改列名

dataFrame.withColumnRenamed("gender", "sex").show()

2.6 删除列

dataFrame.drop("name").show()

3、SQL语法

通过上面的定义会发现DataFrame是一个底层的数据集对象,并且提供了很多强大的方法。当然Spark同时支持直接执行SQL语句,就像直接操作数据表一样。

首先要注册临时表,然后在临时表上执行SQL 操作。

创建临时表

dataFrame.createOrReplaceTempView("user")

查询临时表

spark.sql("select * from user where name ='zhangsan'").show()

这里需要注意的是,这个临时表只是session范围,即临时的且不能全局方法。如果想全局访问需要创建全局临时表,并使用全局路径访问。即:

dataFrame.createGlobalTempView("user")
spark.sql("select * from global_temp.user where name ='zhangsan'").show()

二、DataSet

强类型的数据集合,需要提供对应的类型信息。

从上面的介绍以及前面RDD章节中可以看到RDD 只关注数据本身,定义时不会涉及元数据信息,而 DataFrame 会提供schema信息,但没有强调数据类型。而DataSet 明确指出需要提供类型信息。

1、创建DataSet

1.1 定义一个样式类

case class Person(name: String, age: Long){}

1.2 加载隐式转换

这里是使用专门的编码器对对象进行序列化,转换过程中自动生成基本数据类型。

import spark.implicits._

1.3 定义数据列表并转换成DataSet对象

val list = List(Person("zhangsan", 25), Person("lisi", 29), Person("wangwu", 30)).toDS()

1.4 获取数据

list.select("name", "age").where('age>25).show()

2、DataSet 基础操作

基本操作和DataFrame 类似,这里不再演示。

三、RDD 、DataFrame 、DataSet 三者之间的关系和转换

1、关系

从前面的定义看, DataFrame 和 DataSet 都是基于RDD构建的数据抽象数据集。

共性:

        三者都是spark下的分布式弹性数据集。

        都是惰性加载,在创建、转换时不会立即执行。

        DataFrame 和 DataSet 都需要加载spark.implicits._ , 都可使用模式匹配。

区别:

        版本支持:

                Spark 1.0 支持RDD;

                Spark 1.3 支持 DataFrame;

                Spark 1.6支持 DadaSet, 并会逐步替代前两者。

        数据结构:

                RDD 只包含数据,不关心数据结构。

                DataFrame 包含数据、数据结构。

                DataSet 包含 数据、数据结构、数据类型。

        支持的数据格式:

                RDD 支持结构化、非结构化数据。

                DataFrame 仅支持 结构化 和半结构化数据。

                DataSet 支持结构化和非结构化数据。

        其他还有如 序列化方式、垃圾回收等区别,有兴趣可以深入了解。

总结:

        三者都是对数据集的抽象,只不过抽象的层次不同,简单理解三者具有包含关系:

        DataSet(DataFrame(RDD))

2、转换

定义一个RDD

val rdd: RDD[(Int, String, Int)] = spark.sparkContext.makeRDD(List((1, "zhangsan", 30), (2, "lisi", 29), (3, "wangwu", 32)))

前面提到RDD 包含数据,不包含数据结构和数据类型,DataFrame 包含数据和数据结构但不包含数据类型,所以底层向上层转换时 需要补充 数据结构或 数据类型,这里构建一个样式类。

case class User(id: Int, name: String, age:Int)

2.1 RDD 转 DataFrame

构建数据结构

val df: DataFrame = rdd.toDF("id", "name", "age")

2.2 DataFrame 转 RDD

df.rdd

2.3 RDD 转 DataSet

val ds: Dataset[User] = rdd.map {
  case (id, name, age) => {
    User(id, name, age)
  }
}.toDS()

2.4 DataSet 转 RDD

ds.rdd

2.5 DataFrame 转 DataSet

val ds: Dataset[User] = df.as[User]

2.6 DataSet 转 DataFrame

ds1.toDF()

至此Spark SQL的基础讲解完成,后续在实践中慢慢摸索更详细更深层的知识。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值