基本概念
本章会涉及一些基本概念,包括数据类型(DataType)、结构类型(StructType)、结构字段(StructField)及元数据(Metadata)。通过本节对这些基本概念的介绍,有利于本章后续内容的展开。
DataType 简介
DataType 是 Spark SQL 的所有数据类型的基本类型,Spark SQL 的所有数据类型都继承自 DataType,DataType 的继承体系如图所示。
从图 中可以看到,Spark SQL 中定义的数据类型与 Java 的基本数据类型大部分都是一致的。由于 Spark SQL 不是本书要讲解的内容,所以读者在这里只需要了解这些内容即可。
Metadata 简介
Metadata 用来保存 StructField 的元数据信息,其本质是底层的 Map[String,Any]。Meta-data 可以对 Boolean、Long、Double、String、Metadata、Array[Boolean]、Array[Long]、Array[Double]、Array[String]和 Array[Metadata]等类型的元数据进行存储或读取。Metadata 属于 Spark SQL 中的内容,这里不多介绍。
StructType 与 StructField
样例类 StructType 与样例类 StructField 共同构建起数据源的数据结构。
StructField 中共定义了 4 个属性:字段名称(name)、数据类型(dataType)、是否允许为 null(nullable)、元数据(metadata)。StructField 的定义如下。
case class StructField(
name: String,
dataType: DataType,
nullable: Boolean = true,
metadata: Metadata = Metadata.empty)
StructType 的属性中最为重要的是类型为 Array[StructField]的 fields,由此可以看出一个 StructType 中可以包括零到多个 StructField。为了便于理解,下面定义了一个简单的 StructType。
val struct =
StructType(
StructField("a", IntegerType, true) ::
StructField("b", LongType, false) ::
StructField("c", BooleanType, false) :: Nil)
对于构建的 struct,可以用以下语句获取名称为 b 的 StructField。
val singleField = struct("b")
如果要获取 struct 中不存在的 StructField,就像下面这样。
val nonExisting = struct("d")
那么 nonExisting 等于 null。
如果想要获取 struct 中的多个 StructField,需要像下面这样使用。
val twoFields = struct(Set("b", "c"))
此时的 twoFields 实际为 StructType(List(StructField(b,LongType,false),StructField(c,BooleanType,false)))。
如果像下面这样获取多个 StructField。
val ignoreNonExisting = struct(Set("b", "c", "d"))
那么其中的 d 会被忽略,此时的 ignoreNonExisting
实际为 StructType(List(StructField(b,LongType,false),StructField(c,BooleanType,false)))。
如果我们以以下代码定义一个新的数据结构 struct。
val innerStruct =
StructType(
StructField("f1", IntegerType, true) ::
StructField("f2", LongType, false) ::
StructField("f3", BooleanType, false) :: Nil)
val struct = StructType(
StructField("a", innerStruct, true) :: Nil)
那么我们可以使用这个 schema 创建 Row,就像下面这样。
val row = Row(Row(1, 2, true))