Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 在不同的保存模式下,saveAsTable和insertInto之间有什么区别?_Apache Spark - Fatal编程技术网

Apache spark 在不同的保存模式下,saveAsTable和insertInto之间有什么区别?

Apache spark 在不同的保存模式下,saveAsTable和insertInto之间有什么区别?,apache-spark,Apache Spark,我正试图在覆盖模式下(对于我的应用程序是必需的)将数据帧写入Hive表(在S3上),并需要在DataFrameWriter的两种方法(Spark/Scala)之间做出选择。从中可以看出,df.write.saveAsTable与df.write.insertInto在以下方面有所不同: saveAsTable使用基于列名的分辨率,而insertInto使用基于位置的分辨率 在追加模式下,saveAsTable更关注现有表的底层架构,以确定某些分辨率 总的来说,它给我的印象是,saveAsTa

我正试图在
覆盖
模式下(对于我的应用程序是必需的)将
数据帧
写入
Hive
表(在
S3
上),并需要在DataFrameWriter的两种方法(Spark/Scala)之间做出选择。从中可以看出,
df.write.saveAsTable
df.write.insertInto
在以下方面有所不同:

  • saveAsTable
    使用基于列名的分辨率,而
    insertInto
    使用基于位置的分辨率
  • 在追加模式下,
    saveAsTable
    更关注现有表的底层架构,以确定某些分辨率
总的来说,它给我的印象是,
saveAsTable
只是
insertInto
的一个更智能的版本。或者,根据用例,您可能更喜欢
insertInto

但是,这些方法中的每一种是否都有自己的一些警告,比如在
saveAsTable
的情况下会有性能损失(因为它包含了更多的功能)?除了文件中所述(不是很清楚)之外,他们的行为是否还有其他差异


编辑-1

有关插入的
文档说明了这一点

将数据框的内容插入到指定的表中

对于
saveAsTable

如果表已经存在,则此函数的行为 取决于模式函数指定的保存模式

现在我可以列出我的疑问了

  • insertInto
    是否总是希望该表存在
  • SaveMode
    s是否对
    插入有任何影响
  • 如果上述答案是肯定的,那么
    • 如果表已经存在,
      saveAsTable
      SaveMode.Append
      insertInto
      之间有什么区别
    • 使用
      SaveMode.Overwrite
      insertInto
      是否有意义

免责声明一段时间以来,我一直在探索
插入
,尽管我远不是这方面的专家,但为了更好地分享这些发现

insertInto
是否总是希望该表存在

(根据表名和数据库)

此外,并非所有表都可以插入,即(永久)表、临时视图或临时全局视图都可以,但不是:

  • 带扣的桌子

  • 基于RDD的表

  • 保存模式对insertInto有影响吗

    (这也是我最近的问题!)

    是的,但只是。在您考虑
    insertInto
    之后,其他3种保存模式没有多大意义(因为它只是插入一个数据集)

    如果表已经存在,则saveAsTable与SaveMode.Append和insertInto之间有什么区别

    这是一个很好的问题!我想说没有,但让我们看一个例子(希望这能证明一些事情)

    使用SaveMode.Overwrite插入有意义吗

    我想是的,因为它非常关注
    SaveMode.Overwrite
    。它只是重新创建目标表

    spark.range(3).write.mode("overwrite").insertInto("my_table")
    scala> spark.table("my_table").show
    +---+
    | id|
    +---+
    |  1|
    |  0|
    |  2|
    +---+
    
    Seq(100, 200, 300).toDF.write.mode("overwrite").insertInto("my_table")
    scala> spark.table("my_table").show
    +---+
    | id|
    +---+
    |200|
    |100|
    |300|
    +---+
    

    另一个重要点,我在将数据插入到SIFB2.xx:/P>>现有的HiVE动态分区表时要考虑

    df.write.mode("append").insertInto("dbName"."tableName")
    
    上面的命令将在本质上映射“df”中的数据,并且只将新分区附加到现有表中


    希望如此,它在决定何时使用“insertInto”时又增加了一点

    我最近开始将我的Hive脚本转换为Spark,我还在学习

    我注意到saveAsTable和insertInto有一个重要的行为,但尚未讨论

    saveAsTable(“schema.table”)删除现有表“schema.table”,并基于“df”模式重新创建新表。现有表的模式变得不相关,不必与df匹配。我被这种行为咬了一口,因为我现有的桌子是ORC,而新创建的桌子是拼花地板(火花默认)

    insertInto(“schema.table”)不会删除现有表,并希望现有表的架构与“df”的架构匹配

    我使用这两个选项检查了表的创建时间,并重申了该行为

    原始表格存储为ORC-Wed Sep 04 21:27:33 GMT 2019

    保存稳定后(存储更改为拼花)-2019年9月4日星期三21:56:23 GMT(创建时间更改)

    放弃并重新创建origina表(ORC)-Wed Sep 04 21:57:38 GMT 2019


    插入后(仍然是ORC)Wed Sep 04 21:57:38 GMT 2019(创建时间未更改)

    我想指出SPARK中的
    SaveAsTable
    insertInto
    之间的主要区别

    在分区表中,
    overwrite
    SaveMode在
    SaveAsTable
    insertInto
    情况下的工作方式不同

    考虑下面的例子,我使用
    SaveAsTable
    方法创建分区表

    hive> CREATE TABLE `db.companies_table`(`company` string) PARTITIONED BY ( `id` date);
    OK
    Time taken: 0.094 seconds
    
    现在我添加了两个新行和两个新分区值

    scala> val companiesDF = Seq(("2020-01-03", "Company1"), ("2020-01-04", "Company2")).toDF("id", "company")
    
    scala> companiesDF.write.mode(SaveMode.Append).partitionBy("id").saveAsTable(targetTable)
    
    scala>spark.sql("select * from db.companies_table").show()
    
    +--------+----------+                                                           
    | company|        id|
    +--------+----------+
    |Company1|2020-01-01|
    |Company2|2020-01-02|
    |Company1|2020-01-03|
    |Company2|2020-01-04|
    +--------+----------+
    
    如您所见,表中添加了两个新行

    现在让我们假设我想要覆盖分区2020-01-02数据

    scala> val companiesDF = Seq(("2020-01-02", "Company5")).toDF("id", "company")
    
    scala>companiesDF.write.mode(SaveMode.Overwrite).partitionBy("id").saveAsTable(targetTable)
    
    根据我们的逻辑,只有分区2020-01-02应该被覆盖,但是
    SaveAsTable
    的情况不同。它将覆盖enter表,如下所示

    scala> spark.sql("select * from db.companies_table").show()
    +-------+----------+
    |company|        id|
    +-------+----------+
    |Company5|2020-01-02|
    +-------+----------+
    
    因此,如果我们只想使用
    SaveAsTable
    覆盖表中的某些分区,这是不可能的

    有关更多详细信息,请参阅此链接。

    我遇到的所有QAs/链接都抱怨Spark本质上覆盖了所有分区(在覆盖模式下),需要一些技巧来绕过这个相当抑制性的缺点Hi Jacek,你知道为什么吗
    scala> val companiesDF = Seq(("2020-01-02", "Company5")).toDF("id", "company")
    
    scala>companiesDF.write.mode(SaveMode.Overwrite).partitionBy("id").saveAsTable(targetTable)
    
    scala> spark.sql("select * from db.companies_table").show()
    +-------+----------+
    |company|        id|
    +-------+----------+
    |Company5|2020-01-02|
    +-------+----------+