大數據組件-sparkSQL是什麼,應用場景,編寫流程,DataSet和DataFrame

1.sparkSQL是什麼

sparkSQL主要是爲了降低一些數據工作者使用門檻的降低,讓一些科學家去編寫一大堆代碼是不現實的,所以產生了SQL查詢模式

2.sparkSQL應用場景

老的sparkcore的入口API是SparkContext其功能主要是處理非結構化數據和半結構化數據而目前時代下數據源一般都是類似mysql,hbase等結構化數據源,所以spark團隊專門針對需求設計了SparkSession入口API,用於實現結構化數據清洗,查詢等一系列操作,而且他還兼容老的sparkContext的所有功能

3.sparkSQL編寫流程

import org.apache.spark.sql.SparkSession
import org.apache.spark.{SparkConf, SparkContext, sql}
import org.junit.Test

class sparkSQLDemo {
  @Test
  def sqlDemo: Unit ={
  	//創建對象
    val spark = new sql.SparkSession.Builder()
      .appName("sql")
      .master("local[4]")
      .getOrCreate()

    import spark.implicits._ //隱式轉換
	
    val sourceRdd = spark.sparkContext.parallelize(Seq(Person("zhangsan",15),Person("lisi",20)))
    val PersonDS: Dataset[Person] = sourceRdd.toDS()
    val resultDS = PersonDS.where('age > 10)
      .where('age < 20)
      .select('name)
      .as[String]

    resultDS.show()
  }
}
case class Person(name:String,age:Int)

4.DataFrame和DataSet

DS是命令式的API 而DF是聲明式(sql)的API

@Test
  def sqlDemo2: Unit ={
    val spark = new sql.SparkSession.Builder()
      .appName("sql")
      .master("local[4]")
      .getOrCreate()

    import spark.implicits._ //隱式轉換

    val sourceRdd = spark.sparkContext.parallelize(Seq(Person("zhangsan",15),Person("lisi",20)))
    val df: DataFrame = sourceRdd.toDF()
    df.createOrReplaceGlobalTempView("person")
    val resultdf = spark.sql("select name from where age>10 and age<20")
    resultdf.show()

(1)DataSet特點

DataSet是一個有數據類型的數據容器,提供了結構化查詢API和類RDD的命令式

import org.apache.spark.{SparkConf, SparkContext, sql}
import org.junit.Test

class sparkSQLDemo {

    @Test
    def dataSet1(): Unit ={
      //1.創建sparkSession
      val spark = new sql.SparkSession.Builder()
        .master("local[6]")
        .appName("dataset1")
        .getOrCreate()
      //2.導入隱式轉換
      import spark.implicits._
      //3.兩種創建ds方式
      //3.1第一種創建ds方式
      val sourceRDD = spark.sparkContext.parallelize(Seq(Person("zhansgan",18),Person("lisi",20)))
      val dataset = sourceRDD.toDS()
	
	 //3.2第二種創建ds方式
	 val dataset = spark.createDataset(Seq(Person("zhansgan",18),Person("lisi",20)))      
	
	

      //4.通過對象來處理
      dataset.filter(item=>item.age>10).show()
      //5.通過字段來處理
      dataset.filter('age>10)
      //6.通過SQL表達式來處理
      dataset.filter("age>10").show()
		
	 //7.dataset轉換爲RDD兩種方式
	 //7.1直接獲取到已經分析和解析過的DataSet的執行計劃,從中拿到RDD
	 val RDD = dataset.queryExecution.toRdd
	
	//7.2通過將DataSet底層的rdd[InternalRow]轉換爲和DataSet相同泛型的RDD
	val RDD = dataset.rdd    

}
  }
case class Person(name:String,age:Int)

(2)DataFrame特點

他的設計是借鑑了pandas的dataframe數據類型而產生的.
他的作用是讓spark處理大規模的結構化數據能更加容易.


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

class sparkSQLDemo {
  
  @Test
  def dataSet2(): Unit = {
    //1.創建sparkSession
    val spark = SparkSession.builder()
      .master("local[6]")
      .appName("dataset1")
      .getOrCreate()
    //2.導入隱式轉換
    import spark.implicits._
    //3.創建df
    val df: DataFrame = Seq(Person("zhansgan", 18), Person("lisi", 20)).toDF()

    //4.df的操作
    //select name from where t.gae > 10
    df.where('age>10)
      .select('name)
      .show()
  }
}
case class Person(name:String,age:Int)

2.1DataFram如何創建

toDF
createDataFrame
DataFrameReader

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

class sparkSQLDemo {

  @Test
  def dataSet2(): Unit = {
    //1.創建sparkSession
    val spark = SparkSession.builder()
      .master("local[6]")
      .appName("dataset1")
      .getOrCreate()
    //2.導入隱式轉換
    import spark.implicits._
    val personsList = Seq(Person("zhansgan",16),Person("lisi",20))
    
    //3.三種創建df方式
    //3.1toDF
    val df1 = personsList.toDF()
    
    //3.2createDataFrame
    val df2 = spark.createDataFrame(personsList)
    
    //3.3read
    val df3 = spark.read.csv("dataset/beijing.csv")
  }
}
case class Person(name:String,age:Int)

2.2示例

(1)數據分析

數據格式內容如下:
在這裏插入圖片描述
我們的需求是:對於這份北京的pm測繪數據,我們要統計每年的每個月東四測量pm的次數

(2)命令式

import org.apache.spark.sql.SparkSession
import org.junit.Test

class sparkSQLDemo {

  @Test
  def dataSet2(): Unit = {
    //1.創建sparkSession
    val spark = SparkSession.builder()
      .master("local[6]")
      .appName("dataset1")
      .getOrCreate()

    import spark.implicits._
    //2.讀取數據集
    val df = spark.read
      .option("header",value = true)
      .csv("dataset/BeijingPM20100101_20151231.csv")

    //2.1查看df的Schema(結構信息)信息,就是mysql的desc查看錶結構的意思
    //df.printSchema()
    df.show()
    //3.處理
    df.select('year,'month,'PM_Dongsi)
      .where('PM_Dongsi=!="NA")
      .groupBy('year,'month)
      .count()
      .show()
    spark.stop()
  }
}

(3)sql式實現


import org.apache.spark.sql.SparkSession
import org.junit.Test

class sparkSQLDemo {

  @Test
  def dataSet2(): Unit = {
    //1.創建sparkSession
    val spark = SparkSession.builder()
      .master("local[6]")
      .appName("dataset2")
      .getOrCreate()

    //2.讀取數據集
    val df = spark.read
      .option("header",value = true)
      .csv("dataset/BeijingPM20100101_20151231.csv")


    //4使用sql語句進行查詢
    //4.1將df註冊成爲臨時表
    df.createOrReplaceGlobalTempView("pm")

    //5.執行查詢
    val resultDf = spark.sql("select year, month, count(PM_Dongsi) from pm where PM_Dongsi != 'NA' group by year, month")
    resultDf.show()
    spark.stop()
  }
}


(3)DataFrame和DataSet區別

我們查看源碼可以發現DataFram就是DataSet[Row]類型
在這裏插入圖片描述DataFrame和DataSet是操作方式都是一樣的,他們唯一的不同就是DataFrame處理數據類型僅能是Row類型,而DataSet可以是任何類型

(4)什麼是Row類型

Row類型對象就是Schema(列名字段)加上一行數據
在這裏插入圖片描述

5.Catalyst優化器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章