为啥即使指定了所有值,Spark SQL 也会为字符串列打开可为空?

Posted

技术标签:

【中文标题】为啥即使指定了所有值,Spark SQL 也会为字符串列打开可为空?【英文标题】:Why does Spark SQL turn nullable on for string column even when all values specified?为什么即使指定了所有值,Spark SQL 也会为字符串列打开可为空? 【发布时间】:2017-03-31 19:11:31 【问题描述】:

所以对于这样的事情:

case class RandomClass(stringOne: String, stringTwo: String, numericOne: Int)
val ds = Seq(
  RandomClass("a", null, 1),  
  RandomClass("a", "x", 3), 
  RandomClass("a", "y", 4), 
  RandomClass("a", null, 5)
).toDS()

ds.printSchema()

结果

root
 |-- stringOne: string (nullable = true)
 |-- stringTwo: string (nullable = true)
 |-- numericOne: integer (nullable = false)

为什么stringOne 会是nullable? 奇怪的是,numericOne 被正确推断。我想我只是错过了有关 Dataset 和 DataFrame API 之间关系的一些信息?

【问题讨论】:

【参考方案1】:

为什么stringOne 可以为空

因为 Scala String 只是一个 Java 字符串,与 Scala 不同,Int 可以是 null。实际内容(null 值是否存在)根本无关紧要。

另见spark why do columns change to nullable true

【讨论】:

【参考方案2】:

Spark 确实根据推断的类型是位于 Scala 对象层次结构的AnyRef 还是AnyVal 一侧对可空性做出最佳猜测,但也请注意,它可能比这更复杂。例如,在处理 Parquet 文件时,出于兼容性目的,所有内容都被推断为nullable

同时,当您创建架构时,您可以根据需要在任何地方简单地设置nullable = true

StructField(fieldName, LongType, nullable = true)

// or using a "DSL"
$"fieldName".long.copy(nullable = false)

【讨论】:

以上是关于为啥即使指定了所有值,Spark SQL 也会为字符串列打开可为空?的主要内容,如果未能解决你的问题,请参考以下文章

Java:为啥即使路径完整,使用 file.exists() 也会给出错误值?

即使在分区数据中,Spark 也会列出所有叶节点

为啥即使存在列,我也会有 ORA-00904?

即使应用程序关闭,Xamarin 也会为数据同步形成后台服务

为啥即使使用限制命令访问结果,SPARK \PYSPARK 也会计算所有内容?

即使指定了投影,Mongodb 也会返回所有字段