SparkSQL学习01

目录

    • 1.SparkSQL特点
      • 1.1易整合
      • 1.2统一的数据访问
      • 1.3兼容Hive
      • 1.4标准的数据连接
    • 2 SparkSQL编程模型=DataFrame=DataSet
      • 2.1 SQL
      • 2.2 DataFrame是什么
      • 2.3 DataSet是什么
      • 2.4 RDD,DataSet,DataFrame
    • 3 SparkSQL核心编程
      • 3.1 编程入口
      • 3.2 SparkSQL基本编程
        • 3.2.1编程入口SparkSession
        • 3.2.2 DSL语法 -->结合SQL中关键字作为函数(算子)的名字传递参数进行编程方式-->接近于RDD编程
        • 3.2.3 导入SparkSession中隐式转换操作,增强sql功能
        • 3.2.4 SQL语法 -->直接写SQL或者HQL语言进行编程【算是SparkSQL主流】

SparkSQL是Spark用于结构化数据处理的Spark模块,是Spark生态体系中的构建在SparkCore基础之上的一个基于SQL的计算模块,不依赖于Hive。

SparkSQL与基本的SparkRDDAPI不同,SparksQL提供的接口为Spark提供了有关数据结构和正在执行的计算的更多信息。在内部,SparkSQL使用这些额外的信息来执行额外的优化。有几种与SparkSQL交互的方法,包括SQL和DatasetAPI。计算结果时,将使用相同的执行引擎,这与用于表示计算的API/语言无关。这种统一意味着开发人员可以轻松地在不同的API之间来回切换,基于API的切换提供了表示给定转换的最自然的方式

  • 结构化数据是什么?
    存储在关系型数据库中的数据,就是结构化数据。
  • 半结构化数据是什么?
    类似xml、json等的格式的数据被称之为半结构化数据。
  • 非结构化数据是什么?
    音频、视频、图片等为非结构化数据。
    换句话说,SparkSQL处理的就是【二维表数据】。

1.SparkSQL特点

1.1易整合

在这里插入图片描述

1.2统一的数据访问

使用相同的连接方式连接不同的数据源
在这里插入图片描述

1.3兼容Hive

在已有的仓库上直接运行SQL或HQL
在这里插入图片描述

1.4标准的数据连接

采用JDBC或者ODBC直接连接
在这里插入图片描述

2 SparkSQL编程模型=DataFrame=DataSet

  • 通过两种方式操作SparkSQL,一种就是SQL,一种就是DataFrame和DataSet。

2.1 SQL

SQL操作的是表,所以要想用SQL进行操作,就需要把SparkSQL对应的编程模型转化为一张表才可以。

2.2 DataFrame是什么

在Spark中, DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格。DataFrame与RDD的主区别在于,前者带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型。这使得Spark SOL得以洞察更多的结构信息,从而对藏于DataFrame背后的数据源以及作用于DataFrame之上的变换进行了针对性的优化,最终达到大幅提升运行时效率的目标。反观RDD, 由于无从得知所存数据元素的具体内部结构,SparkCore只能在stage层面进行简单、通用的流水线优化。
同时,与Hive类似,DataFrame也支持嵌套数据类型struct、array和map)。从API易用性的角度上看,DataFraneAPI提供的是一套高层的关系操作,比函数式的RDDAPI要更加友好,门槛更低。
RDD也是一张的二维表,不过没有表头,表名,字段,字段类型等信息。
DataFrame和DataSet是含有表头,表名,字段,字段类型的一张mysql中的二维表。
在这里插入图片描述
左侧的RDD[Person]虽然以Person为类型参数,但Spak框架本身不了解Person类的内部结构。而右侧的DataFrame却提供了详细的结构信息,使得Spark SQL 可以清楚地知道该数据集中包含哪些列,每列的名称和类型各是什么。

2.3 DataSet是什么

DataSet是分布式数据集合。DataSet是Spark1.6中添加的一个新抽象,是DataFrame的一个扩展。它提供了RDD的优势(强类型,使用强大的lambda函数的能力)以及SparkSQL优化执行引擎的优点。DataSet也可以使用功能性的转换(操作map, fatMap, filter等等)。

  • DataSet是DataFrameAPI的一个扩展,是SparkQL最新的数据抽象
  • 用户友好的API风格,既具有类型安全检查也具有DataFrame的查询优化特性;
  • 用样例类来对DataSet中定义数据的结构信息,样例类中每个属性的名称直接映射到DataSet中的字段名称;
  • DataSet是强类型的。比如可以有DataSet[Car], DataSet[Person]
  • DataFrame是DataSet的特列,DataFrame=DataSet[Row],所以可以通过as方法将DataFrame转换为DataSet。Row是一个类型,跟Car、Person这些的类型一样,所有的表结构信息都用Row来表示。获取数据时需要指定顺序。

一般的,将RDD称之为Spark体系中的第一代编程模型:DataFrame比RDD多了一个Schema元数据信息,被称之为Spark体系中的第二代编程模型:Dataset吸收了RDD的优点(强类型推断和强大的函数式编程)和DataFrame中的优化(SQL优化引擎,内存列存储),成为Spark的最新一代的编程模型

2.4 RDD,DataSet,DataFrame

  • RDD
    【弹性分布式数据集】,是Spark对数据进行的一种抽象,可以理解为Spark对数据的一种组织方式,更简单些说,RDD就是一种数据结构,里面包含了数据和操作数据的方法。
    从字面上就能看出的几个特点:
    • 弹性:
      • 数据可完全放内存或完全放磁盘,也可部分存放在内存,部分存放在磁盘,并可以自动切换
      • RDD出错后可自动重新计算(通过血缘自动容错)
      • 可checkpoint(设置检查点,用于容错),可persist或cache(缓存)里面的数据是分片的(也叫分区,partition),分片的大小可自由设置和细粒度调整
    • 分布式:
      • RDD中的数据可存放在多个节点上
    • 数据集:
      • 数据的集合

相对于与DataFrame和Dataset,RDD是Spark最底层的抽象,目前是开发者用的最多的,但逐步会转向DataFrame和Dataset(当然,这是Spark的发展趋势)

  • DataFrame
    DataFrame:理解了RDD,DataFrame就容易理解些,DataFrame的思想来源于Python的pandas库,RDD是一个数据集,DataFrame在RDD的基础上加了Schema 描述数据的信息,可以认为是元数据,DataFrame曾经就有个名字叫SchemaRDD)
    设RDD中的两行数据长这样:
1张三20
2李四21
3王五22

那么在DataFrame中数据变成这样:

ID:IntName:StringAge:Int
1张三20
2李四21
3王五22

从上面两个表格可以看出,DataFrame比RDD多了一个表头信息 (Schema),像一张表了,DataFrame还配套了新的操作数据的方法等,有了DataFrame这个高一层的抽象后,我们处理数据更加简单了,甚至可以用SQL来处理数据了,对开发者来说,易用性有了很大的提升,不仅如此,通过DataFrameAPI或SQL处理数据,会自动经过Spark优化器(Catalyst)的优化,即使你写的程序或SQL不高效,也可以运行的很快

  • DataSet
    相对于RDD,Dataset提供了强类型支持,也是在RDD的每行数据加了类型约束
    设RDD中的两行数据长这样:
1张三20
2李四21
3王五22

那么在DataFrame中数据变成这样:

ID:IntName:StringAge:Int
1张三20
2李四21
3王五22

那么在DataSet中数据变成这样:

Person(id:Int,Name:String,Age:Int)
Person(1,张三,20)
Person(2,李四,21)
Person(3,王五,22)

目前仅支持Scala、JavaAPI,尚未提供Python的API(所以一定要学习
Scala),相比DataFrame,Dataset提供了编译时类型检查,对于分布式程
序来讲,提交一次作业太费劲了(要编译、打包、上传、运行),到提交到集群运行时才发现错误,实在麻烦,这也是引入Dataset的一个重要原因。
使用DataFrame的代码json文件中并没有score字段,但是能编译通过,但是运行时会报异常,如下图代码所示:

 val df1 = spark.read.json("/tmp/people.json")//json文件中没有score字段,但是能编译通过val df2 = df1.filter("score>60").show()

而使用Dataset实现,会在IDE中报错,出错提前到了编译之前:

val ds1 = spark.read.json(("/tmp/people.json")).as[ People]
// 使用dataset这样写,在IDE中就能发现错误
val ds2 = ds1.filter(_.score < 60)
val ds3 = ds1.filter(_.age < 60)
// 打印
ds3.show()

3 SparkSQL核心编程

3.1 编程入口

SparkCore中,如果想要执行应用程序,需要首先构建上下文环境对象SpakContext,SparkSQL其实可以理解为对SparkCore的一种封装,不仅仅在模型上进行了封装,上下文环境对象也进行了封装。
在老的版本中,SparkSQL提供两种SQL查询起始点:一个叫SQLContext,用于Spark自己提供的SQL查询;一个HiveContext 用于连接Hive的查询。
SparkSession是Spark最新的SQL查询起始点,实质上是SQLContext和HiveContext的组合,所以在SQLContext和HiveContext上可用的API在SparkSession上同样是可以使用的。SparkSession内部封装了sparkContext ,所以计算实际上是由SpakContext完成的。
SparkSession的构建需要依赖SparkConf或者SparkContext。使用工厂构建器(Builder方式)模式创建SparkSession。

3.2 SparkSQL基本编程

3.2.1编程入口SparkSession
val session = SparkSession.builder.appName("test")  // 执行项目名称.master("local[*]") //选中本地执行方式// .enableHiveSupport() //开启支持Hive相关操作.getOrCreate() //创建session对象
3.2.2 DSL语法 -->结合SQL中关键字作为函数(算子)的名字传递参数进行编程方式–>接近于RDD编程
//无法读取表结构,优化为下行
//  val frame: DataFrame = session.read.json("data/people.json") val frame: DataFrame = session.read.json(session.sparkContext.wholeTextFiles("data/people.json").values)//DSL语法 -->结合SQL中关键字作为函数(算子)的名字传递参数进行编程方式//        -->接近于RDD编程frame.printSchema()  //查看二维表结构/*运行结果:root|-- age: long (nullable = true)|-- height: double (nullable = true)|-- name: string (nullable = true)|-- province: string (nullable = true)*/frame.show()  //相当于查看表中信息-->select * from people/*运行结果:+---+------+-------+--------+|age|height|   name|province|+---+------+-------+--------+| 10| 168.8|Michael|    广东|| 30| 168.8|   Andy|    福建|| 19| 169.8| Justin|    浙江|| 32| 188.8| 王启峰|    广东|| 10| 168.8|   John|    河南|| 19| 179.8|   Domu|    浙江|+---+------+-------+--------+*/frame.show(3) //相当于查看表中前3行信息/*运行结果:+---+------+-------+--------+|age|height|   name|province|+---+------+-------+--------+| 10| 168.8|Michael|    广东|| 30| 168.8|   Andy|    福建|| 19| 169.8| Justin|    浙江|+---+------+-------+--------+only showing top 3 rows*///针对性查询某列数据-->select name,age from peopleframe.select("name","age").show()/*运行结果:+-------+---+|   name|age|+-------+---+|Michael| 10||   Andy| 30|| Justin| 19|| 王启峰| 32||   John| 10||   Domu| 19|+-------+---+*/
3.2.3 导入SparkSession中隐式转换操作,增强sql功能
import session.implicits._frame.select($"name",$"age").show()/*运行结果:+-------+---+|   name|age|+-------+---+|Michael| 10||   Andy| 30|| Justin| 19|| 王启峰| 32||   John| 10||   Domu| 19|+-------+---+*///涉及到列运算时,每列都必须使用$符号//涉及到列运算时,每列也可以使用单引号字段名形式//等价于 select name,height-1,age+10 from peopleframe.select($"name",$"height"-1,'age+10).show()/*运行结果:+-------+------------+----------+|   name|(height - 1)|(age + 10)|+-------+------------+----------+|Michael|       167.8|        20||   Andy|       167.8|        40|| Justin|       168.8|        29|| 王启峰|       187.8|        42||   John|       167.8|        20||   Domu|       178.8|        29|+-------+------------+----------+*///涉及到列运算时,也可以使用new Column方式//可以使用as修改列的别名//等价于select age+10 as age from peopleframe.select(new Column(name="age").+(10)).show()/*运行结果:+----------+|(age + 10)|+----------+|        20||        40||        29||        42||        20||        29|+----------+*/frame.select(new Column(name="age").+(10).as("age")).show()/*运行结果:+---+|age|+---+| 20|| 40|| 29|| 42|| 20|| 29|+---+*///分组聚合-->统计不用年龄的人数frame.select("age").groupBy("age").count().show()/*运行结果:+---+-----+|age|count|+---+-----+| 19|    2|| 32|    1|| 10|    2|| 30|    1|+---+-----+*///条件查询-->获取年龄超过18岁的frame.select("name","age","height").where("age>20").limit(4).show()/*运行结果:+------+---+------+|  name|age|height|+------+---+------+|  Andy| 30| 168.8||王启峰| 32| 188.8|+------+---+------+*/
3.2.4 SQL语法 -->直接写SQL或者HQL语言进行编程【算是SparkSQL主流】

注意:如果使用SQL的必要前提就是需要将数据转换为表

/*PS:创建表的参数为表名SQL语法操作中提供两种表:createOrReplaceTempView -->创建普通的临时表,作用域为当前session应用范围内有效createOrReplaceGlobalTempView -->创建普通的全局临时表,是当前application中可以使用,会覆盖原来数据createGlobalTempView --> 创建全局临时表,作用域为在整个当前application范围内有效,不会覆盖原来数据使用全局临时表时需要全路径访问:如global_temp.表名没有Replace关键字的global,不会覆盖,如创建,再创建,会报错有Replace关键字的global,会覆盖,如已经创建,再创建,会覆盖*/frame.createGlobalTempView("people")session.sql("""|select * from global_temp.people|""".stripMargin).show()/*运行结果:+---+------+-------+--------+|age|height|   name|province|+---+------+-------+--------+| 10| 168.8|Michael|    广东|| 30| 168.8|   Andy|    福建|| 19| 169.8| Justin|    浙江|| 32| 188.8| 王启峰|    广东|| 10| 168.8|   John|    河南|| 19| 179.8|   Domu|    浙江|+---+------+-------+--------+*/frame.createOrReplaceGlobalTempView("people_2")frame.createOrReplaceTempView("people_1")  //这个操作比较常用session.sql("""|select|age,|count(1) as countz|from people_1|group by age|""".stripMargin).show()/*运行结果:+---+------+|age|countz|+---+------+| 19|     2|| 32|     1|| 10|     2|| 30|     1|+---+------+*/

参考自:https://www.bilibili.com/video/BV1WA411273z?p=5&spm_id_from=pageDriver&vd_source=6bd7b38d1d3cdff6e483a47870f6d418

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/694409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

掌握web控件定位技巧,提升页面操作效率!

简介 在做 Web 自动化时&#xff0c;最根本的就是操作页面上的元素&#xff0c;首先要能找到这些元素&#xff0c;然后才能操作这些元素。工具或代码无法像测试人员一样用肉眼来分辨页面上的元素。那么要如何定位到这些元素&#xff0c;本章会介绍各种定位元素的方法。 web 控…

【前端】前端三要素之DOM

写在前面&#xff1a;本文仅包含DOM内容&#xff0c;JavaScript传送门在这里&#xff0c;BOM传送门在这里。 本文内容是假期中刷的黑马Pink老师视频&#xff08;十分感谢Pink老师&#xff09;&#xff0c;原文保存在个人的GitLab中&#xff0c;如果需要写的网页内容信息等可以评…

vue3 + ts + echart 实现柱形图表

首先封装Echart一个文件 代码如下 <script setup lang"ts"> import { ECharts, EChartsOption, init } from echarts; import { ref, watch, onMounted, onBeforeUnmount } from vue;// 定义props interface Props {width?: string;height?: string;optio…

pclpy 窗口可视化多个点云

pclpy 窗口可视化多个点云 一、算法原理二、代码三、结果1.可视化结果 四、相关数据五、问题与解决方案1.问题2.解决 一、算法原理 原理看一下代码写的很仔细的。。目前在同一个窗口最多可视化两个点云。。 二、代码 from pclpy import pcldef CloudShow(cloud1, cloud2):&q…

04 动力云客之登录后获取用户信息+JWT存进Redis+Filter验证Token + token续期

1. 登录后获取用户信息 非常好实现. 只要新建一个controller, 并调用SS提供的Authentication对象即可 package com.sunsplanter.controller;RestController public class UserController {GetMapping(value "api/login/info")public R loginInfo(Authentication a…

C++ 基础算法 双指针 数组元素的目标和

给定两个升序排序的有序数组 A 和 B &#xff0c;以及一个目标值 x 。 数组下标从 0 开始。 请你求出满足 A[i]B[j]x 的数对 (i,j) 。 数据保证有唯一解。 输入格式 第一行包含三个整数 n,m,x &#xff0c;分别表示 A 的长度&#xff0c;B 的长度以及目标值 x 。 第二行包…

使用静态CRLSP配置MPLS TE隧道

正文共&#xff1a;1591 字 13 图&#xff0c;预估阅读时间&#xff1a;4 分钟 静态CRLSP&#xff08;Constraint-based Routed Label Switched Paths&#xff0c;基于约束路由的LSP&#xff09;是指在报文经过的每一跳设备上&#xff08;包括Ingress、Transit和Egress&#xf…

使用alist连接百度网盘和阿里云盘挂载到本地磁盘

1、下载alist软件 alist软件下载地址&#xff1a;https://github.com/alist-org/alist 跳转后&#xff0c;找到对应的windows版本 2 、下载后解压&#xff0c;并启动服务 注意&#xff1a;alist的启动方式不是传统的双击启动&#xff0c;需要用命令提示符,启动服务 下载完成…

平时积累的FPGA知识点(9)

平时在FPGA群聊等积累的FPGA知识点&#xff0c;第9期&#xff1a; 31 ldpc的license是什么&#xff1f; 解释&#xff1a;Xilinx公司的Zynq UltraScale RFSoC系列芯片进行项目开发&#xff0c;在某些芯片型号中&#xff0c;自身带有SD-FEC硬核资源&#xff0c;具体查询方式&a…

Aster实现一台电脑当两台使——副屏搭配键鼠

前言&#xff1a;笔者每年回家&#xff0c;都面临着想要和小伙伴一起玩游戏&#xff0c;但小伙伴没有电脑/只有低配电脑的问题。与此同时&#xff0c;笔者自身的电脑是高配置的电脑&#xff0c;因此笔者想到&#xff0c;能否在自己的电脑上运行游戏&#xff0c;在小伙伴的电脑上…

MKS T3BI集成蝶阀说明T3B-T3PRS-232Supplement

MKS T3BI集成蝶阀说明T3B-T3PRS-232Supplement

Vue自定义指令的三个方法

目录 ​编辑 介绍 创建方法&#xff1a; min.js注册 script setup中使用 script中使用&#xff1a; 指令钩子 钩子参数 简化形式 对象字面量 在组件上使用 介绍 除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外&#xff0c;Vue 还允许你注册自定义的指令…

Codeforces Round 927 (Div. 3) LR-remainders的题解

原题描述&#xff1a; C.LR-remains 每次测试时限&#xff1a;2 秒 每次测试的内存限制&#xff1a;256 兆字节 输入&#xff1a;标准输入 输出&#xff1a;标准输出 样例1输入&#xff1a; 4 4 6 3 1 4 2 LRRL 5 1 1 1 1 1 1 LLLLL 6 8 1 2 3 4 5 6 RLLLRR 1 10000 1000…

MySQL初识——安装配置

文章目录 1. MySQL卸载2. 获取MySQL官方yum源安装包3. 安装4. 启动MySQL5. 登录6. 配置配置文件 Tips&#xff1a; 本章是Centos 7安装配置myql&#xff0c;配置操作用的是root权限 1. MySQL卸载 首先我们先查看一下系统中是否有mysql服务 ps axj | grep mysql如果有&#xf…

Vue2路由组件练习

Vue2路由组件练习 1. 演示效果 2. 代码分析 2.1. 安装 vue-router 命令&#xff1a;npm i vue-router 应用插件&#xff1a;Vue.use(VueRouter) 2.2. 创建路由文件 在 src 文件夹下&#xff0c;创建router文件夹&#xff0c;并在该文件夹创建index.js文件 2.3. 导入依赖…

K8S实战:Centos7部署Kubernetes1.20.0集群

目录 一、准备工作1.1、创建3台虚拟机1.1.1、下载虚拟机管理工具1.1.2、安装虚拟机管理工具1.1.3、下载虚Centos镜像1.1.4、创建3台虚拟机1.1.5、设置虚拟机网络环境 1.2、虚拟机基础配置&#xff08;3台虚拟机进行相同处理&#xff09;1.2.1、配置host1.2.2、关闭防火墙1.2.3、…

String字符串,FastJson常用操作方法

JSON字符串操作 1、创建配置环境 # 引入测试包testImplementation group: org.springframework.boot, name: spring-boot-starter-test, version: 2.2.6.RELEASE # 创建测试类RunWith(SpringRunner.class)SpringBootTestpublic class JsonTest {Testpublic void test(){Syste…

关于Linux中使用退格键出现^H的问题解决

关于Linux中使用退格键出现^H的问题解决 今天在Linux下执行脚本和监听端口的输入时候&#xff0c;不小心输错内容想要删除用退格键发现变成了^H&#xff0c;从网上查了资料并且实际应用了一下&#xff08;我的虚拟机是CentOS7&#xff09;。 使用ctrl退格键即可成功删除内容 …

LeetCode.105. 从前序与中序遍历序列构造二叉树

题目 105. 从前序与中序遍历序列构造二叉树 分析 这道题是告诉我们一颗二叉树的前序和中序&#xff0c;让我们根据前序和中序构造出整颗二叉树。 拿到这道题&#xff0c;我们首先要知道前序的中序又怎样的性质&#xff1a; 前序&#xff1a;【根 左 右】中序&#xff1a;…

Linux用到的命令

1 压缩文件 tar -czf wonderful.tar.gz pm 这个命令的作用就是创建一个以.tar.gz结尾的包文件&#xff0c;然后调用gzip程序将当前目录下的pm文件夹压缩到这个以.tar.gz结尾的文件里面去