0 ,别忘了引包 :
import spark.implicits._
1 ,SparkSQL 介绍 :
- SparkSQL 脱离了 Hive 的限制。
- SparkSQL 支持查询原生的 RDD。 RDD 是 Spark 平台的核心概念,是 Spark 能够高效的处理大数据的各种场景的基础。
- 能够在 Scala 中写 SQL 语句。支持简单的 SQL 语法检查,能够在 Scala 中写 Hive 语句访问 Hive数据,并将结果取回作为 RDD 使用。
2 ,spark on Hive ( 常用 ) 和 Hive on Spark
- Spark on Hive: Hive 只作为储存角色,Spark 负责 sql 解析优化,执行。
1 ,存储 : hive
2 ,sql 解析 : spark
3 ,执行查询操作 : spark - Hive on Spark:Hive 即作为存储又负责 sql 的解析优化,Spark 负责执行。
1 ,存储 : hive
2 ,sql 解析 : hive
3 ,执行查询操作 : spark
3 ,DataFrame
- DataFrame 也是一个分布式数据容器。
1 ,与 RDD 类似,然而 DataFrame 更像传统数据库的二维表格,除了数据以外,还掌握数据的结构信息,即 schema。
2 ,与 Hive 类似,DataFrame 也支持嵌套数据类型(struct、array和map)
3 ,从 API 易用性的角度上 看, DataFrame API 提供的是一套高层的关系操作,比函数式的 RDD API 要更加友好,门槛更低。 - DataFrame 的底层封装的是 RDD,只不过 RDD 的泛型是 Row 类型。
4 ,SparkSQL 的数据源,可以是 :
- JSON 类型的字符串
- JDBC
- Parquent
- Hive
- HDFS
5 ,SparkSQL 底层架构 :
首先拿到 sql 后解析一批未被解决的逻辑计划,再经过分析得到分析后的逻辑计划,再经过一批优化规则转换成一批最佳优化的逻辑计划,再经过 SparkPlanner 的策略转化成一批物理计划,随后经过消费模型转换成一个个的 Spark 任务执行。
6 ,谓词下推(predicate Pushdown)
- spark 采用的是后者,先过滤,再合并。
7 ,spark 读取 json 格式文件 : json 文件 ( json )
{"name":"zhangsan","age":20}
{"name":"lisi"}
{"name":"wangwu","age":18}
{"name":"a","age":19}
{"name":"zhangsan1","age":20}
{"name":"lisi1"}
{"name":"wangwu1","age":18}
{"name":"a1","age":19}
{"name":"zhangsan2","age":20}
{"name":"lisi2"}
{"name":"wangwu2","age":18}
{"name":"a2","age":19}
{"name":"zhangsan3","age":20}
{"name":"lisi3"}
{"name":"wangwu13","age":18}
{"name":"a3","age":19}
{"name":"zhangsan4","age":20}
{"name":"lisi4"}
{"name":"wangwu4","age":18}
{"name":"a4","age":19}
8 ,sparkSql 读 json 数据 : ( 表数据,表信息 )
package day04
import org.apache.spark.sql.{DataFrame, SparkSession}
object SparkSqlTest {
def main(args: Array[String]): Unit = {
// spark 上下文
val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
// RDD[Rows]
val frame: DataFrame = spark.read.json("./data/json")
// 打印数据信息
frame.show(10)
// 表信息
frame.printSchema()
spark.close()
}
}
9 ,拿出来 10 条数据 :
val rows: Array[Row] = frame.take(10)
10 ,select : select name,age from tablename :
val df01: DataFrame = df.select(df.col("name"),df.col("age"))
11 ,判断 :
- 代码 :
import spark.implicits._
val df01: DataFrame = df.select(df.col("name").equalTo("zhangsan"),df.col("age"))
- 结果 :
12 ,where :
import spark.implicits._
val df1: Dataset[Row] = df.select(df.col("name"),df.col("age")).filter("name='zhangsan' or name='zhangsan1'")
13 ,排序 :
import spark.implicits._
val df1: Dataset[Row] = df.select(df.col("name"),df.col("age")).sort($"name".desc,$"age".asc)
14 ,select + 别名 + 排序 :
import spark.implicits._
val df1: Dataset[Row] = df.select($"name".alias("n"),$"age".alias("a")).sort($"a".asc)
15 ,select … where …
import spark.implicits._
val df1: Dataset[Row] = df.select($"name",$"age").where($"name".equalTo("zhangsan"))
16 ,分组,count :
import spark.implicits._
val df1: DataFrame = df.select($"name",$"age").groupBy("name").count()
17 ,分组 ,排序 ,topN :
package day04
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}
object SparkSqlTest {
def main(args: Array[String]): Unit = {
// spark 上下文
val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
// RDD[Rows]
val df: DataFrame = spark.read.json("./data/json")
import spark.implicits._
val rows: Array[Row] = df.select($"name",$"age").groupBy("name").count().sort($"count".desc).take(3)
rows.foreach(println)
spark.close()
}
}
18 ,select name,age from table where age > 18
package day04
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}
object SparkSqlTest {
def main(args: Array[String]): Unit = {
// spark 上下文
val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
// RDD[Rows]
val df: DataFrame = spark.read.json("./data/json")
import spark.implicits._
val res: Dataset[Row] = df.select($"name",$"age").where($"age">18)
res.show()
spark.close()
}
}
19 ,直接写 sql :
package day04
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}
object SparkSqlTest {
def main(args: Array[String]): Unit = {
// spark 上下文
val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
// RDD[Rows]
val df: DataFrame = spark.read.json("./data/json")
df.createOrReplaceTempView("person")
val df1: DataFrame = spark.sql("select name,age from person where age > 18")
df1.show()
spark.close()
}
}
20 ,临时视图( 常用 ),全局视图 :
- 临时视图 : df.createOrReplaceTempView(“person”)
不跨会话 - 全局视图 : df.createOrReplaceGlobalTempView(“person”)
夸会话 - 跨会话例子 : 不常用
package day04
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}
object SparkSqlTest {
def main(args: Array[String]): Unit = {
// spark 上下文
val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
// RDD[Rows]
val df: DataFrame = spark.read.json("./data/json")
df.createOrReplaceGlobalTempView("person")
spark.sql("select name,age from global_temp.person where age > 18").show()
val spark2: SparkSession = spark.newSession()
spark2.sql("select name,age from global_temp.person where age > 18").show()
}
}
- 注意 : 前一次如果不跨会话,就认为是局部表了,以后也跨不了会话了 。
21 ,总结 :
- 列的前后,谁在前,谁在后 :
ascII 码排序。 - 列类型 : 自动推断。
- 创建临时表 : 2 种。
- df.show : 默认显示前 20 条数据。
22 ,彩蛋 : 嵌套 json
- json 数据 : jsonQian
{"name":"zhangsan","age":20,"info":{"a":1,"b":2}}
{"name":"lisi","info":{"c":3,"d":4}}
{"name":"wangwu","age":19,"info":{"e":5,"f":6}}
{"name":"a","age":18,"info":{"g":7,"h":8}}
{"name":"zhangsan","age":17,"info":{"i":9,"j":0}}
{"name":"lisi","info":{"l":11,"m":12}}
{"name":"wangwu","age":16,"info":{"n":1,"p":"o"}}
- 代码 :
package day04
import org.apache.spark.sql.{DataFrame, SparkSession}
object JsonQianTest {
def main(args: Array[String]): Unit = {
// spark 上下文
val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
// RDD[Rows]
val df: DataFrame = spark.read.json("./data/jsonQian")
df.createOrReplaceTempView("person")
spark.sql("select name,age,info.a,info.b from person").show()
spark.stop()
}
}
23 ,json 数组 :
- 数据 :
{"name":"zhangsan","age":20,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"lisi","info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"wangwu","age":19,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"a","age":18,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"zhangsan","age":17,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"lisi","info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"wangwu","age":16,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
- 代码 :
spark.sql("select name,age,info[0].a from person").show()