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(列名字段)加上一行數據