Spark SQL 是Spark用于结构化数据(structured data)处理的Spark模块

Hive:基于Hadoop的SQL引擎工具,目的是为了简化MapReduce的开发,提高开发效率,可以把SQL转化成MapReduce程序(因为大数据统计用的是新的代码方式)

Spark SQL 的前身是Shark,受Hive发展的制约

Shark分为SparkSQL(兼容Hive)和Hive on Spark(计划将Spark作为Hive的底层引擎之一)

SparkSQL为了简化RDD的开发

写SQL语句时底层会自动把它转化成RDD

特点:

  • 易整合
    无缝整合了SQL查询核Spark编程
  • 通用性
    用相同的方式连接不同的数据源
  • 兼容Hive
  • 标准数据连接
    通过JDBC或者ODBC来连接

DataFrame,DataSet,RDD 都有分区的概念

DataFrame和DataSet 有完全相同的成员函数,区别只是每一行的数据类型不同

DataFrame其实是DataSet的一个特例 type DataFrame=DataSet[Row]

DataSet----->DataFrame----->RDD


DataFrame

DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格

RDD更关注数据,DataFrame更关注数据的结构

RDD:

Person()


DataFrame:

Name

Age

Height

String

int

Double

DataFrame也是懒执行,但性能比RDD高

原因:底层执行一些优化策略

读取Json文件

val dr=spark.read.json("/home/wwx/桌面/user.json")

dr中的内容

dr: org.apache.spark.sql.DataFrame = [age: bigint, username: string]

显示数据

dr.show

输出

+---+--------+
|age|username|
+---+--------+
| 30|zhangsan|
| 20|zhangsan|
| 40|zhangsan|
+---+--------+

生成临时表

df.createTempView("user")

执行sql语句



简化了RDD

DataFrameAPI允许我们使用DataFrame而不用去注册临时表或者生成SQL表达式。DataFrameAPI既有transformation操作也有action操作

SparkSession是创建DataFrame和执行Sql的入口

创建DataFrame有三种方式:

  • 通过Spark的数据源进行创建
  • 从一个存在的RDD转换
  • 从HiveTable进行查询返回
  1. 通过Spark数据源创建
    tip:如果从内存中读取数据,Spark知道数据类型具体是什么。如果是数字,默认为Int;但是如果从文件中读取数据,不确定类型,所以用bigint接收,可以和Long类型转换,不能和Int转换。
  • 读取Json文件创建DataFrame
df.createOrReplaceTempView("user")
  • 对DataFrame创建一个临时表 (View 只能查询,不能修改)
spark.sql("select avg(age) from user").show()
  • 查询
spark.sql("select avg(age) from user").show()

创建全局范围的表

df.createOrReplaceGlobalTempView("user")
//global_temp前缀
spark.sql("select * from global_temp.user").show

DSL语法

不用创建临时视图

tip:涉及到运算时,每列必须使用$,或者采用引号表达式:单引号+字段名

df.select("age")
df.select($"age"+1)//  $表示引用
df.select('age+1)
df.filter('age>23)  // filter过滤
df.groupBy("age").count.show //
  1. RDD转换为DataFrame
    tip:由于是在内存中,类型确定
  • 先创建RDD
val rdd=sc.makeRDD(List(1,2,3,4))
  • 转换为DataFrame
val df=rdd.toDF("id") //二维数组,赋予列名
  • 变回RDD
df.rdd  
//去掉列名,变成行ROW
res17: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[42]

DataSet(最方便)

DataSet是分布式弹性数据集,是对DataFrame的一个扩展,加入了类型,更关注类型本身

也是惰性加载

一行的数据当做一个对象

list.toDS 
//DataFrame到DataSet,给他一个类型
case class Emp(age:Long,username:String)
val ds=df.as[Emp]//as[案例类]

//DataSet到DataFrame,去掉类型,保留结构
ds.toDF

//RDD到DS,前提,RDD里是案例类
rdd.toDS

//DS到RDD
ds.rdd