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 ~]#
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