概述
Spark SQL是Spark中的一个模块,负责结构化数据的处理。它跟Spark RDD API不一样,Spark SQL提供的接口会提供更多关于数据和执行计算的信息。在内部,Spark SQL使用这些额外的信息去执行额外的优化。可以通过SQL 和 Dataset API与Spark SQL进行交互。当使用同一个执行引擎得到的计算结果,它是不会依赖于使用的API/编程语言。这意味着开发人员能更容易的在不同API进行切换。
SQL
Spark SQL可以执行SQL的查询,也可以从现有的hive中读取数据。当从另一种编程语言中运行SQL时,结果将作为一个dataset/dataframe返回。可以通过命令行或者JDBC/ODBC与SQL进行交互。
其实Spark SQL的功能不仅仅只是SQL的功能,它比SQL拥有更多的功能。
Datasets and DataFrames
一个Dataset是一个分部的数据集。Dataset是Spark 1.6中新增的一个新接口它有利于RDDs和Spark SQL中的优化引擎。一个Dataset可以JVM的对象中构建还可以被transformations函数(map,flatMap,filter,etc)操作。Dataset的API可以用于Scala和java。不适用于Python和R语言。
一个DataFrame是一个被加入列名的Dataset。从概念上理解可以等同于关系型数据库里的一张表。DataFrame的构建数据源有很多,例如:结构化文件,Hive中的表,外部数据库,或者已存在的RDDs。DataFrame API 可以用于Scala,java,Python 和 R语言。Scala API中,DataFrame进进是Dataset[Row]的别名。Java API中为Dataset<Row>
创建一个DataFrames
package com.hihi.learn.sparkSql
import com.hihi.learn.sparkSql.DatasetsDemo.Person
import org.apache.spark.sql.types.{StringType, StructField, StructType}
import org.apache.spark.sql.{DataFrame, Row, SparkSession}
import scala.collection.mutable.ArrayBuffer
object DataFrameDemo {
case class Person(name: String, age: Long)
def main(args: Array[String]): Unit = {
// 创建SparkSession,此为spark SQL的入口
val spark = SparkSession
.builder()
.appName("Spark SQL basic example")
.master("local[2]")
.getOrCreate()
import spark.implicits._
//Creating DataFrames
val df = spark.read.format("json").load("E:\\spark-branch-2.2\\examples\\src\\main\\resources\\people.json")
//df.show()
/*
+----+-------+
| age| name|
+----+-------+
|null|Michael|
| 30| Andy|
| 19| Justin|
+----+-------+
*/
// 使用算子操作DataFrame
//UntypedDatasetOperations(df)
// 使用SQL编程方式
RunningSqlQueriesProgrammatically(spark, df)
// Interoperating with RDDs
val peopleDF = spark.sparkContext.textFile("E:\\spark-branch-2.2\\examples\\src\\main\\resources\\people.txt")
.mapPartitions(its => {
var arrPerson = ArrayBuffer[Person]()
for (it <- its) {
val arr = it.split(",")
arrPerson += Person(arr(0), arr(1).trim.toLong)
}
arrPerson.toIterator
})
.toDF().show
// Programmatically Specifying the Schema
val personDS4 = spark.sparkContext.textFile("E:\\spark-branch-2.2\\examples\\src\\main\\resources\\people.txt")
val schemaString = "name age"
val fields = schemaString.split(" ").map(StructField(_, StringType, nullable = true))
val schema = StructType(fields)
val rowRDD = personDS4
.map(_.split(","))
.map(attributes => Row(attributes(0), attributes(1).trim))
val peopleDF2 = spark.createDataFrame(rowRDD, schema)
peopleDF2.show()
spark.stop()
}
def UntypedDatasetOperations(df:DataFrame): Unit = {
// 打印Schema
df.printSchema()
// root
// |-- age: long (nullable = true)
// |-- name: string (nullable = true)
// 查询 name
df.select("name").show
// +-------+
// | name|
// +-------+
// |Michael|
// | Andy|
// | Justin|
// +-------+
// 查询age > 21的数据
df.filter("age > 21").show
// +---+----+
// |age|name|
// +---+----+
// | 30|Andy|
// +---+----+
// 使用分组
df.groupBy("age").count.show()
// +----+-----+
// | age|count|
// +----+-----+
// | 19| 1|
// |null| 1|
// | 30| 1|
// +----+-----+
}
def RunningSqlQueriesProgrammatically(spark: SparkSession, df: DataFrame) : Unit = {
// 注册一张临时表
df.createOrReplaceTempView("people")
spark.sql("select name, age from people").show()
// +----+-------+
// | age| name|
// +----+-------+
// |null|Michael|
// | 30| Andy|
// | 19| Justin|
// +----+-------+
spark.sql("select name, age from people where name = 'Andy'").show
// +----+---+
// |name|age|
// +----+---+
// |Andy| 30|
// +----+---+
}
}
创建一个Datasets
package com.hihi.learn.sparkSql
import org.apache.spark.sql.{Row, SparkSession}
import org.apache.spark.sql.types.{StringType, StructField, StructType}
import scala.collection.mutable.ArrayBuffer
object DatasetsDemo {
case class Person(name: String, age: Long)
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("DatasetsDemo")
.master("local")
.getOrCreate()
// Creating Datasets
import spark.implicits._
val personDS = Seq(Person("Hihi", 22), Person("Tom", 11)).toDS
personDS.show
val personDS2 = spark.read.format("json").load("E:\\spark-branch-2.2\\examples\\src\\main\\resources\\people.json").as[Person]
personDS2.show
spark.stop()
}
}