Spark SQL编程实战案例

             Spark SQL编程实战案例

                                     作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.Spark SQL编程之DataFrame篇

  博主推荐阅读:
    https://www.cnblogs.com/yinzhengjie2020/p/13193293.html

二.Spark SQL编程之DataSet

  博主推荐阅读:
    https://www.cnblogs.com/yinzhengjie2020/p/13197064.html

三.DataFrame与DataSet的互操作

[root@hadoop101.yinzhengjie.org.cn ~]# vim /tmp/user.json
[root@hadoop101.yinzhengjie.org.cn ~]# 
[root@hadoop101.yinzhengjie.org.cn ~]# cat /tmp/user.json
{"name":"yinzhengjie","passwd":"2020"}
{"name":"Jason","passwd":"666666"}
{"name":"Liming","passwd":"123"}
{"name":"Jenny","passwd":"456"}
{"name":"Danny","passwd":"789"}
[root@hadoop101.yinzhengjie.org.cn ~]# 
[root@hadoop101.yinzhengjie.org.cn ~]# vim /tmp/user.json        #创建测试数据
scala> import spark.implicits._                        #温馨提示,在执行下面的案例操作前,需要先导入隐式转换哟~
import spark.implicits._

scala> 

1>.DataFrame转换为DataSet

scala> val df = spark.read.json("/tmp/user.json")            #创建DataFrame
df: org.apache.spark.sql.DataFrame = [name: string, passwd: string]

scala> case class User(name: String, passwd: String)          #创建样例类
defined class User

scala> val ds = df.as[User]                        #通过样例类将DataFrame转换为DataSet
ds: org.apache.spark.sql.Dataset[User] = [name: string, passwd: string]

scala> ds.show
+-----------+------+
|       name|passwd|
+-----------+------+
|yinzhengjie|  2020|
|      Jason|666666|
|     Liming|   123|
|      Jenny|   456|
|      Danny|   789|
+-----------+------+


scala> 

2>.DataSet转换为DataFrame

scala> ds                #当前DataSet是上一个案例的对象
res11: org.apache.spark.sql.Dataset[User] = [name: string, passwd: string]

scala> val df = ds.toDF        #将DataSet转换为DataFrame
df: org.apache.spark.sql.DataFrame = [name: string, passwd: string]

scala> df.show
+-----------+------+
|       name|passwd|
+-----------+------+
|yinzhengjie|  2020|
|      Jason|666666|
|     Liming|   123|
|      Jenny|   456|
|      Danny|   789|
+-----------+------+


scala> 

四.RDD,DataFrame和DataSet三者之间的关系

  在SparkSQL中Spark为我们提供了两个新的抽象,分别是DataFrame和DataSet。他们和RDD有什么区别呢?首先从版本的产生上来看:
    RDD (Spark1.0) —> Dataframe(Spark1.3) —> Dataset(Spark1.6)

  如果同样的数据都给到这三个数据结构,他们分别计算之后,都会给出相同的结果。不同是的他们的执行效率和执行方式。
  在后期的Spark版本中,DataSet会逐步取代RDD和DataFrame成为唯一的API接口。

1>.共性

  RDD、DataFrame、Dataset全都是spark平台下的分布式弹性数据集,为处理超大型数据提供便利

  三者都有惰性机制,在进行创建、转换,如map方法时,不会立即执行,只有在遇到Action如foreach时,三者才会开始遍历运算。
  
三者都会根据spark的内存情况自动缓存运算,这样即使数据量很大,也不用担心会内存溢出。
  
三者都有partition的概念
  
三者有许多共同的函数,如filter,排序等
  
在对DataFrame和Dataset进行操作许多操作都需要导入隐式转换(import spark.implicits._)进行支持

  DataFrame和Dataset均可使用模式匹配获取各个字段的值和类型

2>.区别

  RDD:
    RDD一般和spark mlib同时使用
    RDD不支持sparksql操作

  DataFrame:
    与RDD和Dataset不同,DataFrame每一行的类型固定为Row,每一列的值没法直接访问,只有通过解析才能获取各个字段的值
    DataFrame与Dataset一般不与spark mlib同时使用
    DataFrame与Dataset均支持sparksql的操作,比如select,groupby之类,还能注册临时表/视窗,进行sql语句操作
    DataFrame与Dataset支持一些特别方便的保存方式,比如保存成csv,可以带上表头,这样每一列的字段名一目了然.利用这样的保存方式,可以方便的获得字段名和列的对应,而且分隔符(delimiter)可以自由指定。

  Dataset:
    Dataset和DataFrame拥有完全相同的成员函数,区别只是每一行的数据类型不同。
    DataFrame也可以叫Dataset[Row],每一行的类型是Row,不解析,每一行究竟有哪些字段,各个字段又是什么类型都无从得知,只能用上面提到的getAS方法或者共性中的第七条提到的模式匹配拿出特定字段。而Dataset中,每一行是什么类型是不一定的,在自定义了case class之后可以很自由的获得每一行的信息
    Dataset在需要访问列中的某个字段时是非常方便的,然而,如果要写一些适配性很强的函数时,如果使用Dataset,行的类型又不确定,可能是各种case class,无法实现适配,这时候用DataFrame即Dataset[Row]就能比较好的解决问题。

五.IDEA创建SparkSQL程序

  博主推荐阅读:
    https://www.cnblogs.com/yinzhengjie2020/p/13200300.html
原文地址:https://www.cnblogs.com/yinzhengjie2020/p/13185272.html