SparkSQL:基础概念

目录

  • SparkSQL
    • 1. 基础概念
    • 2.DataFrame
    • 3.SparkSql程序开发(1.x,2.x)
      • (1)SparkSQL1.x
      • (2)SparkSQL2.x

SparkSQL

1. 基础概念

  • Spark SQL是Spark用来处理结构化数据的一个模块,它提供了一个编程抽象叫做DataFrame并且作为分布式SQL查询引擎的作用。
  • 与HiveSql的区别:Hive SQL是通过转换成MapReduce任务,然后提交到集群上执行,简化了编写MapReduce的程序的复杂性。但由于MapReduce这种计算模型执行效率比较慢,Spark SQL的应运而生。SparkSQL是一个SQL解析引擎,将SQL解析成特殊的RDD(DataFrame),然后在Spark集群中运行
  • SparkSQL是用来处理结构化数据的(需要先将非结构化的数据转换成结构化数据)
  • SparkSQL的特点
    - 易整合
    - 统一的数据访问格式(SparkSQL支持统一的数据源,支持读取多种类型的数据)
    - 兼容Hive(元数据库、SQL语法、UDF、序列化、反序列化机制)
    - 标准的数据连接(JDBC,ODBC,还可以对接常见的BI工具)

2.DataFrame

  • 官网概念

与RDD类似,DataFrame也是一个分布式数据容器。然而DataFrame更像传统数据库的二维表格,除了数据以外,还记录数据的结构信息,即schema。同时,与Hive类似,DataFrame也支持嵌套数据类型(struct、array和map)。从API易用性的角度上 看,DataFrame API提供的是一套高层的关系操作,比函数式的RDD API要更加友好,门槛更低。由于与R和Pandas的DataFrame类似,Spark DataFrame很好地继承了传统单机数据分析的开发体验。

  1. 理解:DataFrame是特殊的RDD,也是一种抽象RDD+schema=>DataFrame。与RDD一样,DataFrame中不存放数据,里面存放的结构化数据的描述信息(DataFrame的表头,描述了有多少列,每一列数叫什么名字、什么类型、能不能为空等)
    SparkSQL:基础概念_第1张图片

3.SparkSql程序开发(1.x,2.x)

(1)SparkSQL1.x

SparkSql 1.x和2.x版本最大的区别在于:
1.x版本通过对SparkContext进行包装增强,创建SQLContext对象,将普通RDD转换成DataFrame;
2.x版本有独立的编程api—SparkSession 作为程序的入口。

编写SparkSql1.x方法有两种:sql和DataFrame的api(DSL)。

  1. sql方式

方法一

   1.创建sparkContext,然后再创建SQLContext
   2.先创建RDD,对数据进行整理,然后关联case class,将非结构化数据转换成结构化数据
   3.显示的调用toDF方法将RDD转换成DataFrame
   4.注册临时表
   5.执行SQL(Transformation,lazy)
   6.执行Action

方法二

   1.创建sparkContext,然后再创建SQLContext
   2.先创建RDD,对数据进行整理,然后关联Row,将非结构化数据转换成结构化数据
   3.定义schema
   4.调用sqlContext的createDataFrame方法
   5.注册临时表
   6.执行SQL(Transformation,lazy)
   7.执行Action
/**
*方法一
*/
object SparkSql1 {
  def main(args: Array[String]): Unit = {
    //提交的这个程序可以连接到Spark集群中
    val conf = new SparkConf().setAppName("SparkSql1").setMaster("local[4]")
    //创建连接
    val sc = new SparkContext(conf)
    //sparkContext不能创建特殊的RDD(DataFrame)
    //将SparkContext包装进而增强
    val sqlContext = new SQLContext(sc)
    //创建特殊的RDD(DataFrame),就是有schema信息的RDD
    //先有一个普通的RDD,然后再关联上schema,进而转成DataFrame
    val lines = sc.textFile("hdfs://node01:8020/person")
    //将数据进行整理
    val boyRDD: RDD[Boy] = lines.map(line => {
      val fields = line.split(",")
      val id = fields(0).toLong
      val name = fields(1)
      val age = fields(2).toInt
      var fv = fields(3).toDouble
      Boy(id, name, age, fv)
    })
    //还是一个RDD,有了shcma信息
    //将RDD转成DataFrame
    //导入隐式转换
    import sqlContext.implicits._
    val bdf: DataFrame = boyRDD.toDF
    //变成df后就可以用两种API进行编程
    //把df先注册临时表
    bdf.registerTempTable("t_boy")
    //书写sql(sql方法其实是Transformation)
    val result: DataFrame = sqlContext.sql("SELECT * FROM t_boy ORDER BY fv desc,age asc")
    //查看结果 触发action
    result.show()
    sc.stop()
  }
}
case class Boy(id:Long,name: String,age:Int,fv:Double)
/**
*方法一
*/
object SparkSql2 {
  def main(args: Array[String]): Unit = {
    ...
    ...
  //  数据进行整理
    val boyRDD: RDD[Row] = lines.map(line => {
      val fields = line.split(",")
      val id = fields(0).toLong
      val name = fields(1)
      val age = fields(2).toInt
      var fv = fields(3).toDouble
      Row(id, name, age, fv)
    })
    
    //结果类型,其实就是表头,用于描述DataFrame
    val schema= StructType(List(
      StructField("id",LongType,true),
      StructField("name",StringType,true),
      StructField("age",IntegerType,true),
      StructField("fv",DoubleType,true)
    ))
    //将ROWRDD关联schema
    val bdf: DataFrame = sqlContext.createDataFrame(boyRDD,schema)

    //变成df后就可以用两种API进行编程

    //把df先注册临时表
    bdf.registerTempTable("t_boy")
    //书写sql(sql方法其实是Transformation)
    val result: DataFrame = sqlContext.sql("SELECT * FROM t_boy ORDER BY fv desc,age asc")
    //查看结果 触发action
    result.show()
    sc.stop()
  }
}
  1. DataFrame API进行操作`
//将ROWRDD关联schema
val bdf: DataFrame = sqlContext.createDataFrame(boyRDD,schema)

//不使用sql方式,不需要注册临时表
import sqlContext.implicits._
val df1: DataFrame = bdf.select("name","age")
                        .orderBy($"fv" desc,$"age" asc)
df1.show()
sc.stop()

(2)SparkSQL2.x

注意:SparkSQL 2.x 的编程API和入口都是SparkSession;不需要创建SparkConf和SparkContext


//spark2.x sql 的编程API(SparkSession)
//是spark2.x sql执行入口
val session = SparkSession.builder()
  .appName("SparkSQL2Test")
  .master("local[*]")
  .getOrCreate()
//常见RDD
val lines: RDD[String] = session
  .sparkContext
  .textFile("hdfs://node01:8020/person")

//将数据进行整理
val boyRDD: RDD[Row] = lines.map(line => {
  val fields = line.split(",")
  val id = fields(0).toLong
  val name = fields(1)
  val age = fields(2).toInt
  var fv = fields(3).toDouble
  Row(id, name, age, fv)
})
//结果类型,其实就是表头,用于描述DataFrame
val schema= StructType(List(
  StructField("id",LongType,true),
  StructField("name",StringType,true),
  StructField("age",IntegerType,true),
  StructField("fv",DoubleType,true)
))
//创建DataFrame
val dataFrame: DataFrame = session.createDataFrame(boyRDD,schema)
import session.implicits._
dataFrame.where($"fv">98)
    .orderBy($"fv" desc,$"age" asc)
dataFrame.show()
session.stop()

你可能感兴趣的:(SparkSQL:基础概念)