Spark sql的简单使用

加载依赖

依赖这个东西,只要注意几个依赖之间的相互关系能够匹配的上就行了,这里需要在idea里面写sql,只需要加上一个spark_sql的依赖就行了
这里的2.11是Scala的版本,如果本地也有Scala,要注意互相之间依赖的关联,如果不太清楚,直接去maven的官网去搜就可了maven官网
在这里插入图片描述

spark sql简单入门

sparksql实际上就是把写出来的sql语法加载成RDD,交到集群中去运行;spark sql可以很好的集成hive,在里面也可以写hivesql,spark core中提供的数据结构是RDD,spark sql提供的数据结构是DataFrame,DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库的二维表格;DataFrame可以从很多数据源构建,比如:已经存在的RDD、结构化文件、外部数据库、Hive表。

在这里插入图片描述

Spark sql简单应用

应用配置

这里的SparkSession是Spark2.0入口,SparkContext是1.0入口

/**
      * SparkSession 是Spark2.0的新入口
      */
    val spark: SparkSession = SparkSession
      .builder()
      .master("local")
      .appName("Demo1SparkSession")
      //设置spark sql产生shuffle后默认的分区数 => 并行度
      // 默认是200,也就是说,这里如果不修改,默认有200个reduce
      .config("spark.sql.shuffle.partitions", 3)
      .getOrCreate()

读取文件

读取文本文件并展示数据

这里读取的不管是csv文件还是txt文件,默认都是csv读取,不过这里要手动指定列头

展示数据这里用到的是show(),不过默认只显示20条,需要显示多要自己加参数

//不管是txt还是csv格式,这里默认都是以csv读取
    spark
      .read
      //这里要手动指定列名,不然列头是_c0,_c1,_c2这样的格式
        .schema("id Int,name String,age Int,gender String,clazz String")
      .csv("D:\\BigDaTa\\JAVA_Project\\ShuJia01\\data\\students.txt")
      .show()

show()将数据完全显示

假如我们这里的数据非常长
在这里插入图片描述
不能被显示完全,就需要在show()中加一个参数
show(false)即可
在这里插入图片描述

读取json文件

//读取json数据
    spark
      .read
//        .format("json")
//      .load("D:\\BigDaTa\\JAVA_Project\\ShuJia01\\data\\一份json数据.json")
      .json("D:\\BigDaTa\\JAVA_Project\\ShuJia01\\data\\一份json数据.json")
      .show()

读取jdbc文件

假设我们这里不知道该如何使用,可以从官网中一步步读取
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里面就包含了各个参数的作用,以及示例代码
在这里插入图片描述

//jdbc读取MySQL数据
    spark.read
      .format("jdbc")
      .option("url", "jdbc:mysql://master:3306/test1")
      .option("dbtable", "emp")
      .option("user", "xxxx")
      .option("password", "xxxxxx")
      .load()
      .show()

在这里插入图片描述

读取压缩格式的文件

//读取压缩格式的文件
    spark
      .read
      .format("orc")
      .load("D:\\BigDaTa\\JAVA_Project\\ShuJia01\\Spark\\data\\parquet")
      .show()

将数据以压缩格式存储

parquet或者orc格式存储
spark.read
      .format("jdbc")
      .option("url", "jdbc:mysql://master:3306/test1")
      .option("dbtable", "emp")
      .option("user", "xxxx")
      .option("password", "xxxxxx")
      .load()
      .write
      .parquet("spark/data/parquet")

spark.read
      .format("jdbc")
      .option("url", "jdbc:mysql://master:3306/test1")
      .option("dbtable", "emp")
      .option("user", "xxxx")
      .option("password", "xxxxxx")
      .load()
      .write
      .mode(SaveMode.Overwrite)
      .orc("spark/data/parquet")

读取数据注册成视图并写SQL

我们可以看到,sparksql可以读取csv、json、jdbc的数据源,并且可以在自身的DatFrame中使用类SQL语言和HiveSQL
在这里插入图片描述

直接写sql

val stuDF: DataFrame = spark
      .read
      //这里要手动指定列名,不然列头是_c0,_c1,_c2这样的格式
      .schema("id Int,name String,age Int,gender String,clazz String")
      .csv("D:\\BigDaTa\\JAVA_Project\\ShuJia01\\data\\students.txt")

    //直接将DataFrame注册成临时视图view
    stuDF.createOrReplaceTempView("stu")
    spark.sql("select * from stu where age>23").show()

在这里插入图片描述

类sql的模式

//类sql的方式,介于sql和代码中间的API
    stuDF.where("age > 23")
      .select("name","id","clazz")
      .show()

在这里插入图片描述

写出文件到别的路径

//统计班级人数
    //需要写出文件到别的地方,就需要write
    stuDF.groupBy("clazz")
      .count()
      .write
      //保存的时候可以指定保存的方式
      //Overwrite 覆盖
      //Append 追加
      .mode(SaveMode.Overwrite)
      .save("spark/data/clazz_cnt")

RDD和DF的相互转换

RDD转换成DF

如果是RDD读取文本文件的数据,比如是学生表的数据,有id,name,age这样的字段,建议将学生信息写成一个样例类,再存入RDD,再转换成DF

//这里通过RDD的方式构建DF,推荐使用样例类来做
    val sc: SparkContext = spark.sparkContext
    val stuRDD: RDD[String] = sc.textFile("D:\\BigDaTa\\JAVA_Project\\ShuJia01\\data\\students.txt")

    val stuRDDMap: RDD[Student] = stuRDD.map(
      stu => {
        val strings: Array[String] = stu.split(",")
        val id: String = strings(0)
        val name: String = strings(1)
        val age: String = strings(2)
        val gender: String = strings(3)
        val clazz: String = strings(4)
        Student(id, name, age, gender, clazz)
      }
    )

    //导入隐式转换
    import spark.implicits._
    val sDF: DataFrame = stuRDDMap.toDF()
    sDF.show()

    val ssDF: DataFrame = stuRDD.toDF()
    ssDF.show(false)

  }

  case class Student(id: String, name: String, age: String, gender: String, clazz: String)

不进行这样操作的话,读取到的数据会是这样的:
在这里插入图片描述
转换成样例类进行读取的话是这样的:这样更方便对数据进行操作
在这里插入图片描述

DF转换成RDD

val rdd: RDD[Row] = sDF.rdd
    rdd.foreach(
      rdd=>{
        val id: String = rdd.getAs[String]("id")
        val name: String = rdd.getAs[String](1)
        println(s"$id,$name")
      }
    )

在这里插入图片描述

rdd.map(rdd=>{
      val id: String = rdd.getAs[String]("id")
      val name: String = rdd.getAs[String]("name")
      (id,name)
    }).foreach(println)

在这里插入图片描述

DF中函数的使用

导入数据表的时候记得指定字段

val spark: SparkSession = SparkSession
      .builder()
      .config("spark.sql.shuffle.partitions", 2)
      .master("local")
      .appName("Demo3DFAPI")
      .getOrCreate()

    // 导入隐式转换
    import spark.implicits._
    // 导入所有的sql函数
    import org.apache.spark.sql.functions._

    val stuDF: DataFrame = spark
      .read
      .schema("id Int,name String,age Int,gender String,clazz String")
      .csv("D:\\BigDaTa\\JAVA_Project\\ShuJia01\\data\\students.txt")

where

推荐使用列表达式的形式

//字符串表达式
    stuDF.where("age > 21").show()
    //列表达式
    stuDF.where($"age" > 21).show()

filter

//filter函数
    stuDF.filter(stu=>{
      val id: Int = stu.getAs[Int]("id")
      if (id < 1500100007){
        true
      }
      else {
        false
      }
    })
      .show()

select

stuDF.select( $"id" ,$"name",$"age" + 100 as "new_age").show()

聚合函数的位置(agg)

这里面在分组之后,要将聚合函数放进agg中才可以使用

//统计每个班不同性别的人数(直接统计人数)
 stuDF.groupBy($"clazz",$"gender")
      .agg(count($"gender")).show()

    stuDF.groupBy($"clazz",$"gender")
      .agg(countDistinct($"gender")).show()

join

//join
    //默认时inner join 可以指定关联的方式
    //关联字段一样时
    stuDF.join(scoDF,"id").show()
    //关联字段不一样时 
    stuDF.join(scoDF,$"id"===$"sid","left").show()

直接写sql

//直接写sql
    stuDF.createTempView("students")
    spark.sql(
      """
        |select
        |   clazz
        |   ,count(distinct id)
        |from students
        |group by clazz
      """.stripMargin).show()

感谢阅读,我是啊帅和和,一位大数据专业大四学生,祝你快乐。

### Spark SQL 使用教程 #### 什么是Spark SQLSpark SQL 是 Apache Spark 中的一个模块,旨在处理结构化数据。它可以无缝集成到现有的 Spark 程序中,并提供了强大的 API 来查询关系型和非关系型数据库中的数据[^3]。 #### Spark SQL 的主要特性 - **统一的数据访问层**:支持多种数据源(如 Hive、Parquet、JSON),并通过 DataFrame 和 Dataset 提供一致的操作接口。 - **性能优化**:采用 Catalyst 查询优化器自动调整执行计划以提高效率。 - **标准兼容性**:完全支持 ANSI SQL 标准语句以及 JDBC/ODBC 接口[^3]。 #### 在IDEA中创建并运行一个简单Spark SQL应用实例 下面给出一段完整的Scala代码示例说明如何通过Spark SQL操作Hive表: ```scala package spark.demo.sql import org.apache.spark.sql.SparkSession object SparkSQLHiveDemo { def main(args: Array[String]): Unit = { // 创建带有hive支持功能的SparkSession对象 val spark = SparkSession.builder() .appName("Spark Hive Demo") .enableHiveSupport() // 启用对 hive 的支持 .getOrCreate() try{ // 执行DDL语句构建测试表格students spark.sql(""" CREATE TABLE IF NOT EXISTS students ( id INT, name STRING, age INT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' """) // 加载外部TXT文档作为学生记录导入新建的学生列表里 spark.sql(s""" LOAD DATA LOCAL INPATH '/root/data/students.txt' INTO TABLE students """) // 展示所有录入的学生资料详情 println("Students Data:") spark.sql("SELECT * FROM students").show() } finally { spark.stop() } } } ``` 该程序首先定义了一个新的 SparkSession 实例,并启用了 Hive 支持选项 `.enableHiveSupport()` 。接着它尝试创建一张名为 `students` 的 Hive 表格,如果这张表不存在的话;随后把位于 `/root/data/students.txt` 路径下的文本文件装载进来填充这个表格内容;最后打印出整个学生的名单信息[^2]。 #### 连接其他存储系统-HBase上的Spark SQL查询 除了传统的RDBMS之外,还可以轻松地与其他NoSQL解决方案比如HBase一起协作工作。这里有一个关于如何设置从 HBase 获取数据再利用 Spark SQL 处理的例子: ```scala val spark = SparkSession.builder() .appName("SparkSQL on HBase") .config("spark.hbase.host", "your_hbase_host") .getOrCreate() // Read data from an existing HBase table. val df = spark.read.format("org.apache.hadoop.hbase.spark"). option("hbase.table","your_table_name"). option("hbase.columns.mapping", "key STRING :key," + "name STRING cf:name,"+ "age INT cf:age"). load() df.createOrReplaceTempView("people") val result = spark.sql("SELECT name, age FROM people WHERE age > 20") result.show() spark.stop() ``` 在这个例子当中,我们指定了要读取哪个具体的 HBase 表(`your_table_name`)还有各个字段之间的映射关系等等细节之后就可以像对待普通的 dataframe 那样对其进行各种各样的 sql 操作了[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

l_dsj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值