本文旨在介紹 Spark 讀取tinyInt字段時酪碘,如何處理精度損失的情況
MySQLDialect
spark中,mysql的方言主要約定了數(shù)據(jù)庫中varbinary、bit和tinyint類型的特殊映射管呵,其他類型使用默認映射,源碼如下:
private case object MySQLDialect extends JdbcDialect {
override def getCatalystType(
sqlType: Int, typeName: String, size: Int, md: MetadataBuilder): Option[DataType] = {
if (sqlType == Types.VARBINARY && typeName.equals("BIT") && size != 1) {
md.putLong("binarylong", 1)
Option(LongType)
} else if (sqlType == Types.BIT && typeName.equals("TINYINT")) {
Option(BooleanType)
} else None
}
....
}
從源碼中可以看出哺窄,當spark取出表的scheme中捐下,類型名為tinyint
的字段,會被處理為Boolean
型萌业。而mysql中tinyint的sqlType都會默認處理為bit坷襟,所以如果數(shù)據(jù)庫中的這類字段中,存儲了0生年、1之外的值婴程,拉取數(shù)據(jù)時則會出現(xiàn)數(shù)據(jù)失真。
處理方式:
在JDBC的URL中加入?yún)?shù):tinyInt1isBit=false
spark JDBC的源碼分析晶框,可以參考文檔:Spark JDBC系列--源碼簡析