Spark SQL RDD、DataFrame、Dataset、反射推断机制 Schema 操作!! ╰+攻爆jí腚メ 2023-01-13 05:57 114阅读 0赞 ### Spark SQL 结构化数据文件处理 ### * * 一、Spark SQL基本概念 * * 1.1 需求 * 1.2 Spark SQL 简介 * 1.3 Spark SQL 架构 * 1.4 Catalyst优化器 五大组件 * 1.5 Spark SQL 工作流程 * 二、掌握 DataFrame、Dataset * * 2.1 DataFrame 简介 * 2.2 创建DataFrame * * 2.2.1 读取数据 * 2.3 DataFrame 保存数据 * 2.4 shell中RDD 转换为 DataFrame * 2.5 DataFrame 常用操作 * * 2.5.1 DSL 风格操作 * 2.5.2 SQL 风格操作 * 2.6 Dataset 介绍与操作 * * 2.6.1 RDD、DataFrame 以及Dataset 区别 * 2.6.2 Dataset 对象的创建 * 三、反射推断机制 Schema -------------------- Mysql+Hive:[1、Centos7 MySQL安装 —— 用网盘简单安装][1_Centos7 MySQL_ _] [2、Hadoop集群搭建及配置⑨——Hive 可靠的安装配置][2_Hadoop_Hive] [3、Spark SQ操作 MySQL数据库和 Hive数据仓库][3_Spark SQ_ MySQL_ Hive] [4、Spark SQL RDD基本操作、RDD—DataFrame、API MySQL][4_Spark SQL RDD_RDD_DataFrame_API MySQL] [5、Spark SQL RDD、DataFrame、Dataset、反射推断机制 Schema 操作!!][4_Spark SQL RDD_RDD_DataFrame_API MySQL] -------------------- -------------------- [8、Hadoop集群搭建及配置⑥ —— Hadoop组件安装及配置][8_Hadoop_ _ Hadoop] [9、Hadoop集群搭建及配置⑦—— Spark&Scala安装配置][9_Hadoop_ Spark_Scala] [10、Hadoop集群搭建及配置⑧——Hbase的安装配置][10_Hadoop_Hbase] [11、eclipse配置连接Hadoop][11_eclipse_Hadoop] [12、eclipse 实现 Hdfs java API][12_eclipse _ Hdfs java API] [13、eclipse 实现 HBase java API][13_eclipse _ HBase java API] [14、Hbase java API 实现增删改查][14_Hbase java API] -------------------- ## 一、Spark SQL基本概念 ## ### 1.1 需求 ### 在很多情况下,开发工程师并不了解Scala语言,也不了解Spark常用API,但又非常想要使用Spark框架提供的强大的数据分析能力。 Spark的开发工程师们考虑到了这个问题,利用SQL语言的语法简洁、学习门槛低以及在编程语言普及程度和流行程度高等诸多优势,从而开发了Spark SQL模块,通过Spark SQL,开发人员能够通过使用SQL语句,实现对结构化数据的处理。 ### 1.2 Spark SQL 简介 ### Spark SQL是Spark用来处理结构化数据的一个模块,它提供了一个编程抽象结构叫做 DataFrame的数据模型(即带有 Schema信息的 RDD ) , Spark SQL作为分布式 SQL查询引擎,让用户可以通过 **SQL**, **Dataframe API** 和 **Dataset API**三种方式实现对结构化数据的处理。 **Spark SQL主要提供了以下三个功能:** * Spark SQL可从各种结构化数据源中读取数据,进行数据分析。 * Spark SQL包含行业标准的 JDBC和 ODBC连接方式,因此它不局限于在 Spark程序内使用SQL语句进行查询。 * Spark SQL可以无缝地将 SQL查询与 Spark程序进行结合,它能够将结构化数据作为Spark中的分布式数据集(RDD)进行查询。 ### 1.3 Spark SQL 架构 ### Spark SQL架构与Hive架构相比,把底层的 MapReduce执行引擎更改为 Spark ,还修改了 Catalyst优化器,Spark SQL快速的计算效率得益于 Catalyst优化器。从 HiveQL被解析成语法抽象树起,执行计划生成和优化的工作全部交给 Spark SQL的Catalyst优化器进行负责和管理。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70] Spark要想很好地支持SQL,需要完成解析( **Parser** )、优化(**Optimizer** )、执行(**Execution** )三大过程。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 1] ### 1.4 Catalyst优化器 五大组件 ### Catalyst优化器在执行计划生成和优化的工作时,离不开内部的五大组件。 * SqlParse:完成SQL语法解析功能,目前只提供了一个简单的SQL解析器; * Analyze:主要完成绑定工作,将不同来源的 Unresolved LogicalPlan和元数据进行绑定,生成Resolved LogicalPlan; * Optimizer:对 Resolved Lo;gicalPlan进行优化,生成 OptimizedLogicalPlan; * Planner:将 LogicalPlan转换成 PhysicalPlan; * CostModel:主要根据过去的性能统计数据,选择最佳的物理执行计划。 ### 1.5 Spark SQL 工作流程 ### 1. 下在解析SQL语句之前,会创建 SparkSession,涉及到表名、字段名称和字段类型的元数据都将保存在 SessionCatalog中; 2. 当调用 SparkSession的 sql()方法时就会使用 SparkSqlParser进行解析 SQL语句,解析过程中使用的 ANTLR进行词法解析和语法解析; 3. 使用 Analyzer分析器绑定逻辑计划,在该阶段, Analyzer会使用 Analyzer Rules,并结合 SessionCatalog,对未绑定的逻辑计划进行解析,生成已绑定的逻辑计划; 4. 使用Optimizer优化器优化逻辑计划,该优化器同样定义了一套规则(Rules) ,利用这些规则对逻辑计划和语句进行迭代处理; 5. 使用 SparkPlanner对优化后的逻辑计划进行转换,生成可以执行的物理计划 SparkPlan; 6. 使用 QueryExecution执行物理计划,此时则调用 SparkPlan的 execute()方法,返回RDDs。 -------------------- ## 二、掌握 DataFrame、Dataset ## ### 2.1 DataFrame 简介 ### * Spark SQL使用的数据抽象并非是RDD ,而是DataFrame。 * 在Spark 1.3.0版本之前, DataFrame被称为 SchemaRDD。 * DataFrame使 Spark具备处理大规模结构化数据的能力。 * 在 Spark中,DataFrame是一种以 RDD为基础的分布式数据集。DataFrame的结构类似传统数据库的二维表格,可以从很多数据源中创建,如结构化文件、外部数据库、Hive表等数据源。 DataFrame可以看作是分布式的 Row对象的集合,在二维表数据集的每一列都带有名称和类型,这就是 **Schema元信息**,这使得Spark框架可获取更多数据结构信息,从而对在DataFrame背后的数据源以及作用于DataFrame之上数据变换进行针对性的优化,最终达到提升计算效率。 ### 2.2 创建DataFrame ### **创建DataFrame的两种基本方式:** * 已存在的RDD调用toDF(方法转换得到DataFrame。 * 通过Spark读取数据源直接创建DataFrame。 若使用 SparkSession方式创建 DataFrame,可以使用 **spark.read**从不同类型的文件中加载数据创建 DataFrame,spark.read的具体操作,如下表所示。 <table> <thead> <tr> <th>读取方法</th> <th align="left">说明</th> </tr> </thead> <tbody> <tr> <td>spark.read.text(“people.txt”)</td> <td align="left">读取 txt 格式文件,创建 DataFrame;</td> </tr> <tr> <td>spark.read.csv (“people.csv”)</td> <td align="left">读取 csv 格式文件,创建 DataFrame;</td> </tr> <tr> <td>spark.read.json(“people.json”)</td> <td align="left">读取 json 格式文件,创建 DataFrame;</td> </tr> <tr> <td>spark.read.parquet(“people.parquet”)</td> <td align="left">读取 parquet 格式文件,创建 DataFrame。</td> </tr> </tbody> </table> -------------------- `/usr/spark/spark-2.4.0-bin-hadoop2.7/examples/src/main/resources` 目录下有两个样例数据 people.json和 people.txt。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 2] #### 2.2.1 读取数据 #### import org.apache.spark.sql.SparkSession val spark=SparkSession.builder().getOrCreate() // 使支持 RDD转换为 DataFrame及后续 sql操作 import spark.implicits._ val df = spark.read.json("file:///usr/spark/spark-2.4.0-bin-hadoop2.7/examples/src/main/resources/people.json") df.show() ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 3] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 4] ### 2.3 DataFrame 保存数据 ### 可以使用spark.write操作,把一个DataFrame保存成不同格式的文件, 例如,把一个名称为df的DataFrame保存到不同格式文件中,- df.write.json("people.json“) df.write.parquet("people.parquet“) df.write.csv("people.csv") 创建一个 DataFrame,把示例文件 people.json,保存成csv格式文件。 val peopleDF = spark.read.format("json").load("file:///usr/spark/spark-2.4.0-bin-hadoop2.7/examples/src/main/resources/people.json") peopleDF.select("name", "age").write.format("csv").save("file:///root/people.json") ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 5]![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 6] -------------------- ### 2.4 shell中RDD 转换为 DataFrame ### val dataRDD = sc.textFile("/spark/person.txt").map(_.split(" ")) case class person(id:Int,name:String,age:Int) val personRDD = dataRDD.map(x=>person(x(0).toInt,x(1),x(2).toInt)) val personDF = personRDD.toDF() personDF.show() personDF.printSchema ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 7] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 8] -------------------- ### 2.5 DataFrame 常用操作 ### ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 9] #### 2.5.1 DSL 风格操作 #### DataFrame 提供了一种特定领域语言( DSL)以方便操作结构化数据,下面是操作: // 打印模式 df.printSchema() // 选择多列 df.select(df("name"),df("age")+1).show() // 条件过滤 df.filter(df("age")>20).show() // 分类聚合 df.groupBy("age").count().show() // 排序 df.sort(df("age").desc).show() // 多列排序 df.sort(df("age").asc,df("name").desc).show() // 对列进行重命名 df.select(df("name").as("username"),df("age")).show() ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 10] #### 2.5.2 SQL 风格操作 #### DataFrame 的强大之处就是可以将它看作一个关系型数据表,然后可以在程序中直接使用 `spark.sql()` 的方法执行SQL查询,结果将作为一个 DataFrame返回。使用SQL风格操作需要将 DataFrame注册为临时表。 // 注册t_person表 personDF.registerTempTable("t_person") // 查询年纪最大的三个人信息 spark.sql("select * from t_person order by age desc limit 3").show() // 查找年龄大于25岁的人信息 spark.sql("select * from t_person where age > 25").show() 【注】:在spark-shell 操作 spark.sql()方法可能会存在运行错误的情况,如果信息显示 `not connect metastore`, 则需要提前把 Hive客户端打开!!!,不然不能运行。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 11] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 12] -------------------- ### 2.6 Dataset 介绍与操作 ### Dataset是从Spark1.6Alpha版本中引入的一个新的数据抽象结构,最终在Spark2.0版本被定义成Spark新特性。Dataset提供了特定域对象中的强类型集合,也就是在RDD的每行数据中添加了类型约束条件,只有约束条件的数据类型才能正常运行。Dataset结合了RDD和DataFrame的优点,并且可以调用封装的方法以并行方式进行转换等操作。 #### 2.6.1 RDD、DataFrame 以及Dataset 区别 #### RDD数据的表现形式,即序号(1) ,此时RDD数据没有数据类型和元数据信息。DataFrame数据的表现形式,即序号(2) ,此时DataFrame数据中添加Schema元数据信息(列名和数据类型,如ID : String ) ,DataFrame每行类型固定为Row类型,每列的值无法直接访问,只有通过解析才能获取各个字段的值。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 13] Dataset数据的表现形式,序号(3)和(4) ,其中序号(3)是在 RDD每行数据的基础之上,添加一个数据类型(value:String)作为 Schema元数据信息。而序号(4)每行数据添加 People强数据类型,在 Dataset\[Person\]中里存放了3个字段和属性, Dataset每行数据类型可自定义,一旦定义后,就具有错误检查机制。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 14] -------------------- #### 2.6.2 Dataset 对象的创建 #### val personDs= spark.createDataset(sc.textFile("/spark/person.txt")) personDs.show() ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 15] // DataFrame 用 as.[ElementType]方法转换为 Dataset; spark.read.text("/spark/person.txt").as[String] // Dataset用 as.[ElementType]toDF()方法转换为 DataFrame spark.read.text("/spark/person.txt").as[String].toDF() ![在这里插入图片描述][20210416171434348.png] -------------------- ## 三、反射推断机制 Schema ## Spark官方提供了两种方法实现从RDD转换得到DataFrame: 1. 利用反射机制来推断包含特定类型对象的Schema,这种方式适用于对已知数据结构的RDD转换; 2. 通过编程接口构造一一个Schema,并将其应用在已 知的RDD数据中。 import org.apache.spark.SparkContext import org.apache.spark.rdd.RDD import org.apache.spark.sql.{ DataFrame, Row, SparkSession} case class Person(id:Int,name:String,age:Int) object CaseClassSchema { def main(args: Array[String]): Unit = { //1.构建SparkSession val spark:SparkSession = SparkSession.builder().appName("CaseClassSchema").master("local[2]").getOrCreate(); //2.获取SparkContext val sc:SparkContext =spark.sparkContext //设置日志打印级别 sc.setLogLevel("WARN") //3.读取文件 val data:RDD[Array[String]] = sc.textFile("D:\\配套代码\\person.txt").map(x=>x.split(" ")); //4.将RDD与样例类关联 val personRdd: RDD[Person] = data.map(x=>Person(x(0).toInt,x(1),x(2).toInt)) //5.获取DF //手动导入隐式转换 import spark.implicits._ val personDF: DataFrame = personRdd.toDF //------------DSL语法操作开始------------- //1、显示DataFrame的数据,默认显示20行 personDF.show() //2、显示DataFrame的schema信息 personDF.printSchema() //3、显示DataFrame记录数 println(personDF.count()) //4、显示DataFrame的所有字段 personDF.columns.foreach(println) //5、取出DataFrame的第一行记录 println(personDF.head()) //6、显示DataFrame中name字段的所有值 personDF.select("name").show() //7、过滤出DataFrame中年龄大于30的记录 personDF.filter($"age" > 30).show() //8、统计DataFrame中年龄大于30的人数 println(personDF.filter($"age">30).count()) //9、统计DataFrame中按照年龄进行分组,求每个组的人数 personDF.groupBy("age").count().show() //-----------DSL语法操作结束------------- //-----------SQL操作风格开始------------- //将DataFrame注册成表 personDF.createOrReplaceTempView("t_person") //传入sql语句,进行操作 spark.sql("select * from t_person").show() spark.sql("select * from t_person where name='zhangsan'").show() spark.sql("select * from t_person order by age desc").show() //-----------SQL操作风格结束------------- //关闭操作 sc.stop() spark.stop() } } ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 16] -------------------- 当 case类不能提前定义Schema时,就需要采用编程方式定义 Schema信息,实现 RDD转换 DataFrame的功能。 1. 创建一个Row对象结构的RDD; 2. 基于StructType类型创建Schema; 3. 通过SparkSession提供的createDataFrame()方法来拼接 Schema ,来实现RDD转换成DataFrame。 import org.apache.spark.SparkContext import org.apache.spark.rdd.RDD import org.apache.spark.sql.types.{ IntegerType, StringType, StructField, StructType} import org.apache.spark.sql.{ DataFrame, Row, SparkSession} object SparkSqlSchema { def main(args: Array[String]): Unit = { //1.创建SparkSession val spark: SparkSession = SparkSession.builder().appName("SparkSqlSchema").master("local[2]").getOrCreate() //2.获取sparkContext对象 val sc: SparkContext = spark.sparkContext //设置日志打印级别 sc.setLogLevel("WARN") //3.加载数据 val dataRDD: RDD[String] = sc.textFile("D:\\配套代码\\person.txt") //4.切分每一行 val dataArrayRDD: RDD[Array[String]] = dataRDD.map(_.split(" ")) //5.加载数据到Row对象中 val personRDD: RDD[Row] = dataArrayRDD.map(x=>Row(x(0).toInt,x(1),x(2).toInt)) //6.创建Schema val schema:StructType= StructType(Seq( StructField("id", IntegerType, nullable = false), StructField("name", StringType, nullable = false), StructField("age", IntegerType, nullable= false) )) //7.利用 personRDD与Schema创建 DataFrame val personDF: DataFrame = spark.createDataFrame(personRDD,schema) //8.DSL操作显示DataFrame的数据结果 personDF.show() //9.将DataFrame注册成表 personDF.createOrReplaceTempView("t_person") //10.sql语句操作 spark.sql("select * from t_person").show() spark.sql("select * from t_person order by age desc").show() spark.sql("select * from t_person order by age desc limit 2").show() spark.sql("select * from t_person where age >25").show() //11.关闭资源 sc.stop() spark.stop() } } ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 17] [1_Centos7 MySQL_ _]: https://blog.csdn.net/weixin_44775255/article/details/115662187 [2_Hadoop_Hive]: https://blog.csdn.net/weixin_44775255/article/details/115663334 [3_Spark SQ_ MySQL_ Hive]: https://blog.csdn.net/weixin_44775255/article/details/115707963 [4_Spark SQL RDD_RDD_DataFrame_API MySQL]: https://blog.csdn.net/weixin_44775255/article/details/115727069 [8_Hadoop_ _ Hadoop]: https://blog.csdn.net/weixin_44775255/article/details/113775449 [9_Hadoop_ Spark_Scala]: https://blog.csdn.net/weixin_44775255/article/details/114518207 [10_Hadoop_Hbase]: https://blog.csdn.net/weixin_44775255/article/details/114676669 [11_eclipse_Hadoop]: https://blog.csdn.net/weixin_44775255/article/details/114799064 [12_eclipse _ Hdfs java API]: https://blog.csdn.net/weixin_44775255/article/details/114809298 [13_eclipse _ HBase java API]: https://blog.csdn.net/weixin_44775255/article/details/114821297 [14_Hbase java API]: https://blog.csdn.net/weixin_44775255/article/details/117446315 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70]: /images/20221022/e7557842781248efa56bf97193f2bc8f.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 1]: /images/20221022/da84543a63c54a96bb6c4f6a385edb98.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 2]: /images/20221022/f7582b0e14db4c9f81e034f8420c96d5.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 3]: /images/20221022/7db518b531cb4543a5a75b1048893e0a.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 4]: /images/20221022/2403543aad4a40dda1185f32e470bed5.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 5]: https://img-blog.csdnimg.cn/20210416153517153.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ==,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 6]: /images/20221022/3d2ca540e9c34c89aeba345025e8fcc9.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 7]: /images/20221022/1c691787495c40dfa1b858dcc2007d1b.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 8]: /images/20221022/666f1049e17048d78fb2c9f09b4e02f6.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 9]: /images/20221022/ad7b17de521e445b8133b4d295a579c7.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 10]: /images/20221022/a660c4d32c2e4643898c4ce3cc103b2c.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 11]: /images/20221022/6ea5960230584154b94ae08727889ea8.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 12]: /images/20221022/2869e84619b74190a51b5a4552c3c2fd.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 13]: /images/20221022/a9e4e0e9bb7d470abffaf3a590c2c980.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 14]: /images/20221022/9d2d0ae4e03c448394dfdfd8f3386856.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 15]: /images/20221022/a2adcfc3d9324eb6aa641b01be18f99a.png [20210416171434348.png]: /images/20221022/8967a855cea74057b0a3eb4840ba55cb.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 16]: /images/20221022/5050319a9f8741778cd1ac1aee2498b2.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDc3NTI1NQ_size_16_color_FFFFFF_t_70 17]: /images/20221022/daa73896cf8b4a3ca3e9979fbcb57f1b.png
相关 反射机制滥用问题:Java反射操作错误示范 在Java中,反射是一种强大的机制,可以让我们在运行时检查类、方法和字段等信息。然而,如果过度使用反射,可能会带来一些问题,如性能下降、安全性降低等。 下面是一个简单的Jav £神魔★判官ぃ/ 2024年09月11日 19:33/ 0 赞/ 25 阅读
相关 Spark SQL将rdd转换为数据集-反射来推断Inferring the Schema Using Reflection 一:解读 官网:[https://spark.apache.org/docs/latest/sql-getting-started.html][https_spark.a 小咪咪/ 2024年02月19日 15:20/ 0 赞/ 6 阅读
相关 3.【Java反射机制】通过反射操作类方式 / @author cf @date 2023/1/29 22:16 @description 类操作 / imp 骑猪看日落/ 2023年10月08日 17:28/ 0 赞/ 17 阅读
相关 Spark SQL RDD、DataFrame、Dataset、反射推断机制 Schema 操作!! Spark SQL 结构化数据文件处理 一、Spark SQL基本概念 1.1 需求 1.2 Spark SQL 简 ╰+攻爆jí腚メ/ 2023年01月13日 05:57/ 0 赞/ 115 阅读
相关 Spark Streaming与Spark SQL结合操作详解 Spark Streaming最强大的地方在于,可以与Spark Core、Spark SQL整合使用,之前已经通 过transform、foreachRDD等算子看到,如何将 谁践踏了优雅/ 2022年12月29日 02:25/ 0 赞/ 255 阅读
相关 Spark SQL中DataSet函数操作 目录 一、DataSet中常见函数详解 二、DataSet中untype详解 三、DataSet中聚合函数详解 四、 ﹏ヽ暗。殇╰゛Y/ 2022年12月27日 01:59/ 0 赞/ 253 阅读
相关 Spark SQL(二)之DataSet操作 一、创建DataSet 使用SparkSession,应用程序可以从现有的RDD,Hive表的或Spark数据源创建DataFrame 。 (1)基于JSON的内容创建 墨蓝/ 2022年11月13日 05:26/ 0 赞/ 149 阅读
相关 spark sql: SparkSession操作hive表 目标: 实现类似于navicat的功能=> 写hql语句,在idea下使用spark sql 一键运行,而不用到shell窗口下运行命令 步骤: 写sql文件 (resour 系统管理员/ 2022年04月18日 05:03/ 0 赞/ 199 阅读
相关 spark sql 操作hbase表 在hbase表 \[ns1:person\] 中有如下数据 hbase(main):073:0> scan 'ns1:person' ROW 左手的ㄟ右手/ 2022年04月13日 05:51/ 0 赞/ 270 阅读
还没有评论,来说两句吧...