Spark SQL初體驗

一、入口-SparkSession

●在spark2.0版本之前

SQLContext是創建DataFrame和執行SQL的入口

HiveContext通過hive sql語句操作hive表數據,兼容hive操作,hiveContext繼承自SQLContext。

●在spark2.0之後

SparkSession 封裝了SqlContext及HiveContext所有功能。通過SparkSession還可以獲取到SparkConetxt。

SparkSession可以執行SparkSQL也可以執行HiveSQL.

二、創建DataFrame

1、創讀取文本文件

1.在本地創建一個文件,有id、name、age三列,用空格分隔,然後上傳到hdfs上

vim /root/person.txt

1 zhangsan 20

2 lisi 29

3 wangwu 25

4 zhaoliu 30

5 tianqi 35

6 kobe 40

上傳數據文件到HDFS上:

hadoop fs -put /root/person.txt  /

2.在spark shell執行下面命令,讀取數據,將每一行的數據使用列分隔符分割

打開spark-shell

/export/servers/ spark-2.2.0-bin-2.6.0-cdh5.14.0/bin/spark-shell

創建RDD

val lineRDD= sc.textFile("hdfs://node01:8020/person.txt").map(_.split(" ")) //RDD[Array[String]]

3.定義case class(相當於表的schema)

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

4.將RDD和case class關聯

val personRDD = lineRDD.map(x => Person(x(0).toInt, x(1), x(2).toInt)) //RDD[Person]

5.將RDD轉換成DataFrame

val personDF = personRDD.toDF //DataFrame

6.查看數據和schema

personDF.show

+---+--------+---+
| id|    name|age|
+---+--------+---+
|  1|zhangsan| 20|
|  2|    lisi| 29|
|  3|  wangwu| 25|
|  4| zhaoliu| 30|
|  5|  tianqi| 35|
|  6|    kobe| 40|
+---+--------+---+

personDF.printSchema

7.註冊表

personDF.createOrReplaceTempView("t_person")

8.執行SQL

spark.sql("select id,name from t_person where id > 3").show

9.也可以通過SparkSession構建DataFrame

val dataFrame=spark.read.text("hdfs://node01:8020/person.txt")

dataFrame.show //注意:直接讀取的文本文件沒有完整schema信息

dataFrame.printSchema

2、讀取json文件

數據文件

使用spark安裝包下的json文件

more /export/servers/ spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/people.json

{"name":"Michael"}

{"name":"Andy", "age":30}

{"name":"Justin", "age":19}

2.在spark shell執行下面命令,讀取數據

val jsonDF= spark.read.json("file:///export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/people.json")

3.接下來就可以使用DataFrame的函數操作     

jsonDF.show

//注意:直接讀取json文件schema信息,因爲json文件本身含有Schema信息,SparkSQL可以自動解析

3、讀取parquet文件

1.數據文件

使用spark安裝包下的parquet文件

more /export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/users.parquet

2.在spark shell執行下面命令,讀取數據

val parquetDF=spark.read.parquet("file:///export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/users.parquet")

3.接下來就可以使用DataFrame的函數操作

parquetDF.show

//注意:直接讀取parquet文件有schema信息,因爲parquet文件中保存了列的信息

4、創建DataSet

1.通過spark.createDataset創建Dataset

val fileRdd = sc.textFile("hdfs://node01:8020/person.txt") //RDD[String]

val ds1 = spark.createDataset(fileRdd)  //DataSet[String]

ds1.show

2.通RDD.toDS方法生成DataSet

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

val data = List(Person("zhangsan",20),Person("lisi",30)) //List[Person]

val dataRDD = sc.makeRDD(data)

val ds2 = dataRDD.toDS  //Dataset[Person]

ds2.show

3.通過DataFrame.as[泛型]轉化生成DataSet

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

val jsonDF= spark.read.json("file:///export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/people.json")

val jsonDS = jsonDF.as[Person] //DataSet[Person]

jsonDS.show

4.DataSet也可以註冊成表進行查詢

jsonDS.createOrReplaceTempView("t_person")

spark.sql("select * from t_person").show

三、兩種查詢風格[先了解]

準備工作

讀取文件並轉換爲DataFrame或DataSet

val lineRDD= sc.textFile("hdfs://node01:8020/person.txt").map(_.split(" "))

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

val personRDD = lineRDD.map(x => Person(x(0).toInt, x(1), x(2).toInt))

val personDF = personRDD.toDF

personDF.show

//val personDS = personRDD.toDS

//personDS.show

DSL風格

SparkSQL提供了一個領域特定語言(DSL)以方便操作結構化數據

1.查看name字段的數據

personDF.select(personDF.col("name")).show

personDF.select(personDF("name")).show

personDF.select(col("name")).show

personDF.select("name").show

2.查看 name 和age字段數據

personDF.select("name", "age").show

3.查詢所有的name和age,並將age+1

personDF.select(personDF.col("name"), personDF.col("age") + 1).show

personDF.select(personDF("name"), personDF("age") + 1).show

personDF.select(col("name"), col("age") + 1).show

personDF.select("name","age").show

//personDF.select("name", "age"+1).show

personDF.select($"name",$"age",$"age"+1).show

4.過濾age大於等於25的,使用filter方法過濾

personDF.filter(col("age") >= 25).show

personDF.filter($"age" >25).show

5.統計年齡大於30的人數

personDF.filter(col("age")>30).count()

personDF.filter($"age" >30).count()

6.按年齡進行分組並統計相同年齡的人數

personDF.groupBy("age").count().show

SQL風格

DataFrame的一個強大之處就是我們可以將它看作是一個關係型數據表,然後可以通過在程序中使用spark.sql() 來執行SQL查詢,結果將作爲一個DataFrame返回

如果想使用SQL風格的語法,需要將DataFrame註冊成表,採用如下的方式:

personDF.createOrReplaceTempView("t_person")

spark.sql("select * from t_person").show

1.顯示錶的描述信息

spark.sql("desc t_person").show

2.查詢年齡最大的前兩名

spark.sql("select * from t_person order by age desc limit 2").show

3.查詢年齡大於30的人的信息

spark.sql("select * from t_person where age > 30 ").show

4.使用SQL風格完成DSL中的需求

spark.sql("select name, age + 1 from t_person").show

spark.sql("select name, age from t_person where age > 25").show

spark.sql("select count(age) from t_person where age > 30").show

spark.sql("select age, count(age) from t_person group by age").show

總結

1.DataFrameDataSet都可以通過RDD來進行創建

2.也可以通過讀取普通文本創建--注意:直接讀取沒有完整的約束,需要通過RDD+Schema

3.通過josn/parquet會有完整的約束

4.不管是DataFrame還是DataSet都可以註冊成表,之後就可以使用SQL進行查詢了! 也可以使用DSL!

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