Spark JDBC中的伪列

时间:2017-12-03 06:41:55

标签: apache-spark apache-spark-sql spark-jdbc

我正在使用查询从MYSQL获取数据,如下所示:

var df = spark.read.format("jdbc")
         .option("url", "jdbc:mysql://10.0.0.192:3306/retail_db")
         .option("driver" ,"com.mysql.jdbc.Driver")
         .option("user", "retail_dba")
         .option("password", "cloudera")
         .option("dbtable", "orders")
         .option("partitionColumn", "order_id")
         .option("lowerBound", "1")
         .option("upperBound", "68883")
         .option("numPartitions", "4")
         .load() 

问题是,我可以在ROWNUM中使用伪列(如Oracle中的RRN(employeeno)或DB2中的option),其中我指定partitionColumn

如果没有,我们可以指定一个不是主键的分区列吗?

2 个答案:

答案 0 :(得分:3)

  

我可以使用伪列(如Oracle中的ROWNUM或DB2中的RRN(employeeno))

TL; DR 可能没有。

虽然Spark并未考虑PRIMARY KEYUNIQUE等约束,但对partitionColumn非常重要要求尚未明确说明文档 - 必须是确定性的

每个执行者使用单独的事务获取它自己的数据。如果数字列不是确定性的(稳定,在事务之间保留),则Spark看到的数据状态可能不一致,并且可能会复制或跳过记录。

由于ROWNUM实现通常是易失性的(取决于非稳定排序并且可能受索引等功能影响),因此partitionColumn无法安全选择。出于同样的原因,你不能使用随机数。

此外,某些供应商可能会进一步限制对伪列的允许操作,使其不适合用作分区列。 For example Oracle ROWNUM

  

ROWNUM值大于正整数的条件测试始终为false。

可能会无声地导致错误的结果。

  

我们可以指定一个不是主键的分区列

是的,只要它满足上述标准。

答案 1 :(得分:-1)

根据Spark's official documentationpartitionColumn可以是任何数字列(不一定是主键列)。

  

partitionColumn必须是相关表格中的数字列。

参考:http://spark.apache.org/docs/latest/sql-programming-guide.html#jdbc-to-other-databases