spark2学习(3) 之Spark SQL

本文介绍了Spark SQL的使用,包括如何创建SparkSession,创建DataFrame,通过编程方式运行SQL查询,以及创建全局临时表。此外,还探讨了从RDD转换为Dataset的两种方法,并强调了Dataset相比RDD的优势。
摘要由CSDN通过智能技术生成

Spark SQL是用于结构化数据处理的Spark模块。与基本的Spark RDD API不同,Spark SQL提供的接口为Spark提供了有关数据结构和正在执行的计算的更多信息。在内部,Spark SQL使额外的优化。有几种与Spark SQL交互的方法,包括SQL和Dataset API。

创建sparksession

import org.apache.spark.sql.SparkSession

val spark = SparkSession
  .builder()
  .appName("Spark SQL basic example")
  .config("spark.some.config.option", "some-value")
  .getOrCreate()

// For implicit conversions like converting RDDs to DataFrames
import spark.implicits._

sparksql默认支持hive的功能。

创建一个DataFrame

可以从RDD,hive,hdfs,来创建DataFrame,读取一个json文件,代码如下:

json文件内容

 

无类型的DataSet操作就是DataFram操作。

dataframe操作手册地址:http://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.functions$

以编程方式运行SQL查询

这里我们将刚刚的dataframe注册成一个临时表(createOrReplaceTempView),然后使用sql语句执行,使用非常方便

全局临时表

上面的临时表当会话关闭后就不存在了,如果我们想要全局的临时表需要添加createGlobalTempView

就ok了

 

创建dataset

数据集与RDD类似,但是,它们不使用Java序列化或Kryo,而是使用专门的编码器来序列化对象以便通过网络进行处理或传输。虽然编码器和标准序列化都负责将对象转换为字节,但编码器是动态生成的代码,并使用一种格式,允许Spark执行许多操作,如过滤,排序和散列,而无需将字节反序列化为对象。

sparkSQL和RDD的交互方式

第一种就是通过对象的反射,首先将文本格式的对象定义成一个case class 类型,然后执行 toDS,然后再注册临时表就ok了,代码如下:

// For implicit conversions from RDDs to DataFrames
import spark.implicits._

// Create an RDD of Person objects from a text file, convert it to a Dataframe
val peopleDF = spark.sparkContext
  .textFile("examples/src/main/resources/people.txt")
  .map(_.split(","))
  .map(attributes => Person(attributes(0), attributes(1).trim.toInt))
  .toDF()
// Register the DataFrame as a temporary view
peopleDF.createOrReplaceTempView("people")

// SQL statements can be run by using the sql methods provided by Spark
val teenagersDF = spark.sql("SELECT name, age FROM people WHERE age BETWEEN 13 AND 19")

// The columns of a row in the result can be accessed by field index
teenagersDF.map(teenager => "Name: " + teenager(0)).show()
// +------------+
// |       value|
// +------------+
// |Name: Justin|
// +------------+

// or by field name
teenagersDF.map(teenager => "Name: " + teenager.getAs[String]("name")).show()
// +------------+
// |       value|
// +------------+
// |Name: Justin|
// +------------+

第二种以编程方式指定

如果无法提前定义案例类,DataFrame则可以通过三个步骤以编程方式创建。

  1. 为原生的RDD创建Row
  2. 创建schema 的StructType 为 Row
  3. 通过SparkSession将schema 和RDD进行绑定

如下:

import org.apache.spark.sql.types._

// Create an RDD
val peopleRDD = spark.sparkContext.textFile("examples/src/main/resources/people.txt")

// The schema is encoded in a string
val schemaString = "name age"

// Generate the schema based on the string of schema
val fields = schemaString.split(" ")
  .map(fieldName => StructField(fieldName, StringType, nullable = true))
val schema = StructType(fields)

// Convert records of the RDD (people) to Rows
val rowRDD = peopleRDD
  .map(_.split(","))
  .map(attributes => Row(attributes(0), attributes(1).trim))

// Apply the schema to the RDD
val peopleDF = spark.createDataFrame(rowRDD, schema)

// Creates a temporary view using the DataFrame
peopleDF.createOrReplaceTempView("people")

// SQL can be run over a temporary view created using DataFrames
val results = spark.sql("SELECT name FROM people")

// The results of SQL queries are DataFrames and support all the normal RDD operations
// The columns of a row in the result can be accessed by field index or by field name
results.map(attributes => "Name: " + attributes(0)).show()
// +-------------+
// |        value|
// +-------------+
// |Name: Michael|
// |   Name: Andy|
// | Name: Justin|
// +-------------+
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值