Spark框架中三者是可以相互转换的,我总结了一些常用的转换操作,希望帮到大家
package com.sparksql
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}
object SparkSqlDataForm {
def main(args: Array[String]): Unit = {
//SparkSession
val spark: SparkSession = SparkSession
.builder()
.master("local")
.appName("DataFrameFromStuctType")
.getOrCreate()
val lineRDD: RDD[String] = spark.sparkContext.textFile("C:\\people.txt")
val peopleRDD:RDD[People] = lineRDD.map(line => {
val linearray: Array[String] = line.split(",")
People(linearray(0), linearray(1).trim.toInt)
})
//peopleRDD.foreach(println(_))
import spark.implicits._
//RDD 转换为 DF : rdd.toDF()
//DataFrame 转换为RDD: df.rdd
//这里是为了给大家做演示,正式使用的时候其实不用sparkContext之后再map,SparkSession读取到的row类型的DF也可以直接调用toDF,并且制定列明,传入的参数是一个不定长的字符串参数
val peopleDF: DataFrame = peopleRDD.toDF() //
//peopleDF.foreach(println(_))
val rdd1: RDD[Row] = peopleDF.rdd
//RDD 转换为 DS: rdd.toDS()
//DataSet 转换为RDD: ds.rdd
val peopleDS: Dataset[People] = peopleRDD.toDS()
//peopleDS.foreach(println(_))
peopleDS.createOrReplaceTempView("people7")
val rdd2: RDD[People] = peopleDS.rdd
//DataSet[Type] : Type类型的DataSet
//DataSet[Row] : DataFrame是Row类型的DataSet
//DataSet转换成DataFrame:
val df2: DataFrame = peopleDS.toDF()
val ds: Dataset[People] = peopleDF.as[People] //DataSet[Row] => DataSet[People]
val ds2: Dataset[P2] = peopleDF.as[P2] //有类型检查,会报错
ds2.foreach(println(_))
peopleDF.map(line=>line.getString(0))
peopleDS.map(line=>line.age)
}
}
case class P2(n:Int)
总的来说RDD是批处理的数据容器,DS是第一代SparkSql正式且相对完善的sql集,DF是现在版本用的最新的sql数据集,DF的出现是因为,DS的好处是有数据泛型,默认是ROW,操作的时候可以用字段或者字段信息转换成表视图的元数据,但是它也有一个效率问题,就是通过它操作数据的时候,是先把目标数据所在的整行数据反序列化出来成一个对象,然后根据字段拿数据,这在效率上不是很友好,所以出现了DF,它是Row类型的DS,有兴趣可以找找其他的资料,总之它可以不再整行的反序列化,而是直接按需获取数据