spark 三种数据集的关系(二)

一个Dataset是一个分布式的数据集,而且它是一个新的接口,这个新的接口是在Spark1.6版本里面才被添加进来的,所以要注意DataFrame是先出来的,然后在1.6版本才出现的Dataset,提供了哪些优点呢?比如强类型,支持lambda表达式,还有还提供了sparksql执行引擎的一些优化,DataFrame里面大部分东西在Dataset里面都是能用的,Dataset它能够通过哪些方式构建?一个是jvm对象,还有一些函数表达式比如map、flatMap、filter等等。这个Dataset可以使用在java和scala语言里面,注意python暂时还不能支持Dataset的API。

1.关于类型方面:

DataSet是带有类型的(typed),例:DataSet<Persono>。取得每条数据某个值时,使用类似person.getName()这样的API,可以保证类型安全。
而DataFrame是无类型的,是以列名来作处理的,所以它的定义为DataSet<Row>。取得每条数据某个值时,可能要使用row.getString(0)或col("department")这样的方式来取得,无法知道某个值的具体的数据类型。
// Load a text file and interpret each line as a java.lang.String
val ds = sqlContext.read.text("/home/spark/1.6/lines").as[String]
//dataframe
val result = ds
  .flatMap(_.split(" "))               // Split on whitespace
  .filter(_ != "")                     // Filter empty words
  .toDF()                              // Convert to DataFrame to perform aggregation / sorting
  .groupBy($"value")                   // Count number of occurences of each word
  .agg(count("*") as "numOccurances")
  .orderBy($"numOccurances" desc)      // Show most common words first
//DataSet,完全使用scala编程,不要切换到DataFrame
 
val wordCount = 
  ds.flatMap(_.split(" "))
    .filter(_ != "")
    .groupBy(_.toLowerCase()) // Instead of grouping on a column expression (i.e. $"value") we pass a lambda function
    .count()

DataFrame和DataSet可以相互转化,df.as[ElementType]这样可以把DataFrame转化为DataSet,ds.toDF()这样可以把DataSet转化为DataFrame。

2.关于schema:

DataFrame带有schema,而DataSet没有schema。schema定义了每行数据的“数据结构”,就像关系型数据库中的“列”,schema指定了某个DataFrame有多少列。

3.数据类型检查

Dataset可以认为是DataFrame的一个特例,主要区别是Dataset每一个record存储的是一个强类型值而不是一个Row,DataSet可以在编译时检查类型。

4.新的概念Encoder

DataSet结合了RDD和DataFrame的优点, 并带来的一个新的概念Encoder
当序列化数据时, Encoder产生字节码与off-heap进行交互, 能够达到按需访问数据的效果, 而不用反序列化整个对象. Spark还没有提供自定义Encoder的API, 但是未来会加入.
原文地址:https://www.cnblogs.com/wqbin/p/11741596.html