【Spark入门(3)】SparkSQL基础

 【时间】2021.12.01

【题目】【Spark入门(3)】SparkSQL基础

目录

一、引言

二、一些重点图

1、RDD与DataFrame

2、RDD、DF、DS三者的相互转换

3、SparkSQL核心编程例子

4、一个UDAF的例子(实现计算平均年龄)

三、思维导图 



一、引言

本文是课程尚硅谷大数据Spark教程的SparkSQL基础部分的思维导图。SparkSQL主要是通过sql语句来简化RDD的开发流程,主要内容包括:

  1. SparkSQL历史(从Hive到Shark,再到剥离Hive依赖的SparkSQL)
  2. 两个数据抽象:DataFrame和DataSet,其中DF是一种以RDD为基础的包含schema 元信息的二维表格数据,属于弱类型;DS是DF的强类型扩展,type DataFrame = Dataset[Row]
  3. SparkSQL 核心编程,包括加载与保存数据,RDD、DF、DS之间的转换等
  4. UDF用户定义函数和UDAF用户定义聚合函数的实现,新版本的Spark统一继承Agreegator即可。

视频链接:SparkSQL基础

二、一些重点图

1、RDD与DataFrame

2、RDD、DF、DS三者的相互转换

3、SparkSQL核心编程例子

1)spark-shell例子:

  • SQL语法

  • DSL语法:

2)IDEA例子:

package com.atguigu.bigdata.spark.sql

import org.apache.spark.SparkConf
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

object Spark01_SparkSQL_Basic {

    def main(args: Array[String]): Unit = {

        // TODO 创建SparkSQL的运行环境
        val sparkConf = new SparkConf().setMaster("local[*]").setAppName("sparkSQL")
        val spark = SparkSession.builder().config(sparkConf).getOrCreate()
        import spark.implicits._


        // TODO 执行逻辑操作

        // TODO DataFrame
        //val df: DataFrame = spark.read.json("datas/user.json")
        //df.show()

        // DataFrame => SQL
//        df.createOrReplaceTempView("user")
//
//        spark.sql("select * from user").show
//        spark.sql("select age, username from user").show
//        spark.sql("select avg(age) from user").show

        // DataFrame => DSL
        // 在使用DataFrame时,如果涉及到转换操作,需要引入转换规则

        //df.select("age", "username").show
        //df.select($"age" + 1).show
        //df.select('age + 1).show

        // TODO DataSet
        // DataFrame其实是特定泛型的DataSet
        //val seq = Seq(1,2,3,4)
        //val ds: Dataset[Int] = seq.toDS()
        //ds.show()

        // RDD <=> DataFrame
        val rdd = spark.sparkContext.makeRDD(List((1, "zhangsan", 30), (2, "lisi", 40)))
        val df: DataFrame = rdd.toDF("id", "name", "age")
        val rowRDD: RDD[Row] = df.rdd

        // DataFrame <=> DataSet
        val ds: Dataset[User] = df.as[User]
        val df1: DataFrame = ds.toDF()

        // RDD <=> DataSet
        val ds1: Dataset[User] = rdd.map {
            case (id, name, age) => {
                User(id, name, age)
            }
        }.toDS()
        val userRDD: RDD[User] = ds1.rdd


        // TODO 关闭环境
        spark.close()
    }
    case class User( id:Int, name:String, age:Int )
}

 4、一个UDAF的例子(实现计算平均年龄)

package com.atguigu.bigdata.spark.sql

import org.apache.spark.SparkConf
import org.apache.spark.sql.expressions.Aggregator
import org.apache.spark.sql.{Dataset, Encoder, Encoders, SparkSession, TypedColumn, functions}

object Spark03_SparkSQL_UDAF2 {

    def main(args: Array[String]): Unit = {

        // TODO 创建SparkSQL的运行环境
        val sparkConf = new SparkConf().setMaster("local[*]").setAppName("sparkSQL")
        val spark = SparkSession.builder().config(sparkConf).getOrCreate()
        import spark.implicits._
        val df = spark.read.json("datas/user.json")

        // 早期版本中,spark不能在sql中使用强类型UDAF操作
        // SQL & DSL
        // 早期的UDAF强类型聚合函数使用DSL语法操作
        val ds: Dataset[User] = df.as[User]

        // 将UDAF函数转换为查询的列对象
        val udafCol: TypedColumn[User, Long] = new MyAvgUDAF().toColumn

        ds.select(udafCol).show


        // TODO 关闭环境
        spark.close()
    }
    /*
     自定义聚合函数类:计算年龄的平均值
     1. 继承org.apache.spark.sql.expressions.Aggregator, 定义泛型
         IN : 输入的数据类型 User
         BUF : 缓冲区的数据类型 Buff
         OUT : 输出的数据类型 Long
     2. 重写方法(6)
     */
    case class User(username:String, age:Long)
    case class Buff( var total:Long, var count:Long )
    class MyAvgUDAF extends Aggregator[User, Buff, Long]{
        // z & zero : 初始值或零值
        // 缓冲区的初始化
        override def zero: Buff = {
            Buff(0L,0L)
        }

        // 根据输入的数据更新缓冲区的数据
        override def reduce(buff: Buff, in: User): Buff = {
            buff.total = buff.total + in.age
            buff.count = buff.count + 1
            buff
        }

        // 合并缓冲区
        override def merge(buff1: Buff, buff2: Buff): Buff = {
            buff1.total = buff1.total + buff2.total
            buff1.count = buff1.count + buff2.count
            buff1
        }

        //计算结果
        override def finish(buff: Buff): Long = {
            buff.total / buff.count
        }

        // 缓冲区的编码操作
        override def bufferEncoder: Encoder[Buff] = Encoders.product

        // 输出的编码操作
        override def outputEncoder: Encoder[Long] = Encoders.scalaLong
    }
}

三、思维导图 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值