SparkSQL

Scala 同时被 2 个专栏收录
6 篇文章 0 订阅
2 篇文章 0 订阅

Spark SQL

SparkSQL介绍

Spark SQL是用于结构化数据、半结构化数据处理的Spark高级模块,可用于从各种结构化数据源,例如JSON(半结构化)文件、CSV文件、ORC文件(ORC文件格式是一种Hive的文件存储格式,可以提高Hive表的读、写以及处理数据的性能)、Hive表、Parquest文件(新型列式存储格式,具有降低查询成本、高效压缩等优点,广泛用于大数据存储、分析领域)中读取数据,然后在Spark程序内通过SQL语句对数据进行交互式查询,进而实现数据分析需求,也可通过标准数据库连接器(JDBC/ODBC)连接传统关系型数据库,取出并转化关系数据库表,利用Spark SQL进行数据分析。

从Spark 2.0开始,Spark将DataFrame和DataSet的API融合到一起,提供了结构化的API,即用户可以通过一套标准的API完成对两者的操作。DataSet具有两个不同的API特性:带类型的API(静态类型)和不带类型的API(动态类型)。在概念上,DataFrame视为通用对象DataSet[Row]集合的别名,其中Row是不带类型的Java虚拟机对象,相比之下,DataSet是带类型的Java虚拟机对象集合,数据类型可以由Scala中的案例类定义或由Java中的类指定。由于Python和R语言在编译时类型是动态的,因此只有不带类型的API,即DataFrame,而无法使用DataSet。

Spark SQL可以三种方式操作数据,包括SQL、DataFrame API、DataSet API。如果从静态类型和运行时安全性的限制进行比较,SQL的限制最弱,DataSet API的限制最强。如果在代码中使用SQL语句进行查询,直到运行时才会发现语法错误,所以一般建议通过交互方式执行,而通过DataFrame和DataSet编程的方式,可以在编译时发现和捕获语法错误,所以编写应用代码时节省了开发人员的时间和成本。
在这里插入图片描述

创建结构化数据

Spark中所有功能的入口点是SparkSession。当启动spark-shell时,系统会自动启动一个SparkSession实例Spark,我们可以在创建DataFrame和DataSet时直接通过Spark调用其中的方法。从Spark 2.0开始,SparkSession提供了Hive功能的内置支持,包括使用HiveQL编写查询,访问Hive UDF以及从Hive表读取数据的功能。要使用这些功能,不需要具有现有的Hive设置。使用SparkSession,应用程序可以从现有的RDD、Hive表或Spark数据源创建DataFrame。

// 使用java.io对象生成json测试文件
import java.io._
import org.apache.spark.sql.SparkSession

//  创建sparkSession对象
val spark = SparkSession.builder()   
    .appName("sparkSQL")  
    .enableHiveSupport()     // 如果是读hive表,添加hive支持  
    .getOrCreate()      // get或者新建

// 创建测试文件:json_file.json
val writer = new PrintWriter(new File("json_file.json"))
writer.write("[{\"name\":\"bob\",\"age\":18},{\"name\":\"alice\",\"age\":116}]")
writer.close()

val spark_df = spark.read.json("json_file.json")    // 返回DataFrame
spark_df.show()

// df结构信息,没有参数方法可以不带括号
spark_df.printSchema

在这里插入图片描述

使用SQL查询

def sql(sqlText : root.scala.Predef.String) : org.apache.spark.sql.DataFrame

spark.sql方法可以通过写sql查询返回DataFrame,查询的表需注册成临时表;

Spark SQL中的本地临时视图是基于会话范围的,如果创建它的会话终止,其也将消失。如果要在所有会话之间共享临时视图,并保持活动状态,直到Spark应用程序终止,可以创建一个全局临时视图。全局临时视图与系统保留的数据库global_temp绑定,必须使用global_temp限定名称引用它,例如SELECT∗FROMglobal_temp.spark_df。

sparkDF.createOrReplaceTempView("tbname")
spark.sql("select * from tbname")

// 注册全局临时表
sparkDF.createGlobalTempView("global_tbname")
spark.sql("select * from global_temp.tbname")

创建DataSet

Spark SQL的Scala接口支持自动将包含案例类的RDD转换为DataFrame。案例类定义了表的架构。案例类的参数名称通过反射机制读取,并成为列的名称。案例类也可以嵌套或包含复杂类型,例如Seqs或Arrays。可以将该RDD隐式转换为DataFrame,然后将其注册为表,可以在后续的SQL语句中使用。

// 创建样本类
case class Person(name:String,age:Long)
// 样本类反射推断创建DS
val caseClassDS = Seq(Person("bob",15)).toDS()

// 也可以使用Seq.toDS,字段名是_1,_2,_3
val seqDS = Seq((1,2,3)).toDS()

// 通过json创建ds
val jsonDS = spark.read.json("json_file.json").as[Person]

// 查看ds表结构
jsonDS.printSchema

// 通过rdd创建DataFrame
val rddDF = spark.sparkContext
    .textFile("text_file.txt")    // 读取txt文件
    .map(_.split(","))      // 逗号分隔
    .map(e -> Person(e(0),e(1).trim.toInt())    // 剔除空格,转化成int类型
    .toDF()    // rdd转化成DataFrame
    
rddDF.createOrReplaceTempView("rdd_tbname")     // 注册临时表
val sparkDF = spark.sql("select name,age from rdd_tbname")        // 使用spark.sql查询

常见的Spark SQL结构化数据操作

函数 描述
select类似于sql的select操作,选择一个或者多个列,可以对列进行变换投影map
selectExpr执行投影时支持强大的sql表达式对列进行转化
filter和where相同,看使用习惯
where类似sql中的where过滤记录行
distinct/dropDuplicates从DataFrame中删除重复的行,distinct全字段去重
sort/orderBy根据列对DataFrame进行排序
limit获取前n行返回DF
union合并两个DF返回新的DF
withColumn用户在DF中添加新列或替换现有列
withColumnRenamed列重命名
drop从DF中删除一列或多列,如果指定的列名不存在,则不执行任何操作
sample根据给定的参数随机选择
randomSplit根据给定的权重将DF分为一个或者多个DF,在机器学习模型训练过程中,通常用于将数据集分为训练集和测试集
join类似于sql的join,内连接,左连杰,右连接,全连接,交叉连接
groupBy类似于sql的groupby ,返回groupby结构
describe计算有关DF中的数字列和字符串列的通用统计信息,比如计数、平均值、标准差、最小值、最大值、任意近似的百分数
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值