ApacheSparkでサポートされている7つの結合タイプの概要

ApacheSparkでサポートされている7つの結合タイプの概要

過去のメモリビッグデータ過去のメモリビッグデータ

データ分析では、2つのデータセットに対して結合操作を実行するのが非常に一般的なシナリオです。この記事では、Sparkでサポートされている5つの結合戦略を紹介しました。この記事では、ApacheSparkでサポートされている結合タイプを紹介します。

Apache Spark 3.0の現在のバージョンでは、次の7つの結合タイプがサポートされています。

•INNER JOINを
•CROSS JOINを
LEFT OUTER JOINを•
登録しよう•RIGHT OUTER
•FULL OUTER JOINを
•LEFTは、SEMI JOINの
•LEFT ANTI JOINを
実装の観点では、実装クラスが参加し、これらの7つのタイプに対応するものとして、以下のとおりです。


object JoinType {
  def apply(typ: String): JoinType = typ.toLowerCase(Locale.ROOT).replace("_", "") match {
    case "inner" => Inner
    case "outer" | "full" | "fullouter" => FullOuter
    case "leftouter" | "left" => LeftOuter
    case "rightouter" | "right" => RightOuter
    case "leftsemi" | "semi" => LeftSemi
    case "leftanti" | "anti" => LeftAnti
    case "cross" => Cross
    case _ =>
      val supported = Seq(
        "inner",
        "outer", "full", "fullouter", "full_outer",
        "leftouter", "left", "left_outer",
        "rightouter", "right", "right_outer",
        "leftsemi", "left_semi", "semi",
        "leftanti", "left_anti", "anti",
        "cross")
      throw new IllegalArgumentException(s"Unsupported join type '$typ'. " +
        "Supported join types include: " + supported.mkString("'", "', '", "'") + ".")
  }
}

今日は、これらの7種類の結合の実装を基礎となるコードから紹介するつもりはありませんが、データアナリストの観点から、これらの種類の結合の意味と使用法を紹介します。以下を紹介する前に、次のように、顧客と注文に関連する2つのテーブルがあるとします。


scala> val order = spark.sparkContext.parallelize(Seq(
     |   (1, 101,2500), (2,102,1110), (3,103,500), (4 ,102,400)
     | )).toDF("paymentId", "customerId","amount")
order: org.apache.spark.sql.DataFrame = [paymentId: int, customerId: int ... 1 more field]
scala> order.show
+---------+----------+------+
|paymentId|customerId|amount|
+---------+----------+------+
|        1|       101|  2500|
|        2|       102|  1110|
|        3|       103|   500|
|        4|       102|   400|
+---------+----------+------+
scala> val customer = spark.sparkContext.parallelize(Seq(
     |     (101,"iteblog") ,(102,"iteblog_hadoop") ,(103,"iteblog001"), (104,"iteblog002"), (105,"iteblog003"), (106,"iteblog004")
     | )).toDF("customerId", "name")
customer: org.apache.spark.sql.DataFrame = [customerId: int, name: string]
scala> customer.show
+----------+--------------+
|customerId|          name|
+----------+--------------+
|       101|       iteblog|
|       102|iteblog_hadoop|
|       103|    iteblog001|
|       104|    iteblog002|
|       105|    iteblog003|
|       106|    iteblog004|
+----------+--------------+
准备好数据之后,现在我们来一一介绍这些 Join 类型。

内部結合

Sparkでは、結合タイプが指定されていない場合、デフォルトはINNERJOINです。INNER JOINは、結合条件を満たすデータのみを返します。これは、次のように、より頻繁に使用する必要があります。


scala> val df = customer.join(order,"customerId")
df: org.apache.spark.sql.DataFrame = [customerId: int, name: string ... 2 more fields]
scala> df.show
+----------+--------------+---------+------+
|customerId|          name|paymentId|amount|
+----------+--------------+---------+------+
|       101|       iteblog|        1|  2500|
|       103|    iteblog001|        3|   500|
|       102|iteblog_hadoop|        2|  1110|
|       102|iteblog_hadoop|        4|   400|
+----------+--------------+---------+------+

上記からわかるように、結合タイプを指定しない場合、デフォルトはINNER JOINです。生成された結果では、Sparkは両方のテーブルに存在するcustomerIdを自動的に削除します。グラフで表す場合、INNERJOINは次のように表すことができます。

ApacheSparkでサポートされている7つの結合タイプの概要

上の写真のピンクの部分は、INNERJOINの結果です。

クロス結合

このタイプの結合は、デカルト積(デカルト積)とも呼ばれます。結合の左側のテーブルのデータの各行は、右側のテーブルのデータの各行と結合されます。結果の行数はm * nであるため、実稼働環境この種の結合は使用しないようにしてください。以下は、CROSSJOINの使用例です。


scala> val df = customer.crossJoin(order)
df: org.apache.spark.sql.DataFrame = [customerId: int, name: string ... 3 more fields]
scala> df.show
+----------+--------------+---------+----------+------+
|customerId|          name|paymentId|customerId|amount|
+----------+--------------+---------+----------+------+
|       101|       iteblog|        1|       101|  2500|
|       101|       iteblog|        2|       102|  1110|
|       101|       iteblog|        3|       103|   500|
|       101|       iteblog|        4|       102|   400|
|       102|iteblog_hadoop|        1|       101|  2500|
|       102|iteblog_hadoop|        2|       102|  1110|
|       102|iteblog_hadoop|        3|       103|   500|
|       102|iteblog_hadoop|        4|       102|   400|
|       103|    iteblog001|        1|       101|  2500|
|       103|    iteblog001|        2|       102|  1110|
|       103|    iteblog001|        3|       103|   500|
|       103|    iteblog001|        4|       102|   400|
|       104|    iteblog002|        1|       101|  2500|
|       104|    iteblog002|        2|       102|  1110|
|       104|    iteblog002|        3|       103|   500|
|       104|    iteblog002|        4|       102|   400|
|       105|    iteblog003|        1|       101|  2500|
|       105|    iteblog003|        2|       102|  1110|
|       105|    iteblog003|        3|       103|   500|
|       105|    iteblog003|        4|       102|   400|
+----------+--------------+---------+----------+------+
only showing top 20 rows

左外部結合

LEFT OUTER JOINは、LEFT JOINと同等です。この結合によって返される結果は誰もが知っていると思いますので、紹介しません。次の3つの表現は同等です。


val leftJoinDf = customer.join(order,Seq("customerId"), "left_outer")
val leftJoinDf = customer.join(order,Seq("customerId"), "leftouter")
val leftJoinDf = customer.join(order,Seq("customerId"), "left")
scala> leftJoinDf.show
+----------+--------------+---------+------+
|customerId|          name|paymentId|amount|
+----------+--------------+---------+------+
|       101|       iteblog|        1|  2500|
|       103|    iteblog001|        3|   500|
|       102|iteblog_hadoop|        2|  1110|
|       102|iteblog_hadoop|        4|   400|
|       105|    iteblog003|     null|  null|
|       106|    iteblog004|     null|  null|
|       104|    iteblog002|     null|  null|
+----------+--------------+---------+------+

図で表すと、LEFT OUTER JOINは次のようになります。結合に参加している左側のテーブルのデータが表示され、右側のテーブルは関連している場合にのみ表示されます。

ApacheSparkでサポートされている7つの結合タイプの概要

右外部結合

LEFT OUTER JOINと同様に、RIGHT OUTERJOINはRIGHTJOINと同等であり、次の3つの記述方法も同等です。


val rightJoinDf = order.join(customer,Seq("customerId"), "right")
val rightJoinDf = order.join(customer,Seq("customerId"), "right_outer")
val rightJoinDf = order.join(customer,Seq("customerId"), "rightouter")
scala> rightJoinDf.show
+----------+---------+------+--------------+
|customerId|paymentId|amount|          name|
+----------+---------+------+--------------+
|       101|        1|  2500|       iteblog|
|       103|        3|   500|    iteblog001|
|       102|        2|  1110|iteblog_hadoop|
|       102|        4|   400|iteblog_hadoop|
|       105|     null|  null|    iteblog003|
|       106|     null|  null|    iteblog004|
|       104|     null|  null|    iteblog002|
+----------+---------+------+--------------+

図で表すと、RIGHT OUTER JOINは次のようになります。結合に参加している右側のテーブルのデータが表示され、左側のテーブルは関連している場合にのみ表示されます。

ApacheSparkでサポートされている7つの結合タイプの概要

完全外部結合

FULL OUTER JOINの意味は誰もが知っているはずなので、その意味は紹介しません。FULL OUTER JOINには、次の4つの記述方法があります。


val fullJoinDf = order.join(customer,Seq("customerId"), "outer")
val fullJoinDf = order.join(customer,Seq("customerId"), "full")
val fullJoinDf = order.join(customer,Seq("customerId"), "full_outer")
val fullJoinDf = order.join(customer,Seq("customerId"), "fullouter")
scala> fullJoinDf.show
+----------+---------+------+--------------+
|customerId|paymentId|amount|          name|
+----------+---------+------+--------------+
|       101|        1|  2500|       iteblog|
|       103|        3|   500|    iteblog001|
|       102|        2|  1110|iteblog_hadoop|
|       102|        4|   400|iteblog_hadoop|
|       105|     null|  null|    iteblog003|
|       106|     null|  null|    iteblog004|
|       104|     null|  null|    iteblog002|
+----------+---------+------+--------------+

FULL OUTER JOINは、次の図で表すことができます。

ApacheSparkでサポートされている7つの結合タイプの概要

左半結合

LEFT SEMI JOINを知っておく必要のある人は比較的少ないです。LEFTSEMIJOINは右側のテーブルに一致するデータのみを返し、LEFT SEMIJOINは左側のテーブルのデータのみを返します。右側のテーブルのデータは表示されません。 、次の3つの書き込み方法はすべて同等です。


val leftSemiJoinDf = order.join(customer,Seq("customerId"), "leftsemi")
val leftSemiJoinDf = order.join(customer,Seq("customerId"), "left_semi")
val leftSemiJoinDf = order.join(customer,Seq("customerId"), "semi")
scala> leftSemiJoinDf.show
+----------+---------+------+
|customerId|paymentId|amount|
+----------+---------+------+
|       101|        1|  2500|
|       103|        3|   500|
|       102|        2|  1110|
|       102|        4|   400|
+----------+---------+------+

上記の結果からわかるように、LEFT SEMIJOINは実際にはIN / EXISTSで書き換えることができます。


scala> order.registerTempTable("order")
warning: there was one deprecation warning (since 2.0.0); for details, enable `:setting -deprecation' or `:replay -deprecation'
scala> customer.registerTempTable("customer")
warning: there was one deprecation warning (since 2.0.0); for details, enable `:setting -deprecation' or `:replay -deprecation'
scala> val r = spark.sql("select * from order where customerId in (select customerId from customer)")
r: org.apache.spark.sql.DataFrame = [paymentId: int, customerId: int ... 1 more field]
scala> r.show
+---------+----------+------+
|paymentId|customerId|amount|
+---------+----------+------+
|        1|       101|  2500|
|        3|       103|   500|
|        2|       102|  1110|
|        4|       102|   400|
+---------+----------+------+

LEFT SEMI JOINは、次の図で表すことができます。

ApacheSparkでサポートされている7つの結合タイプの概要

左アンチジョイン

LEFT SEMI JOINとは異なり、LEFT ANTI JOINは、右側のテーブルと一致しない左側のテーブルからのデータのみを返します。また、次の3つの書き方も同等です。


val leftAntiJoinDf = customer.join(order,Seq("customerId"), "leftanti")
val leftAntiJoinDf = customer.join(order,Seq("customerId"), "left_anti")
val leftAntiJoinDf = customer.join(order,Seq("customerId"), "anti")
scala> leftAntiJoinDf.show
+----------+----------+
|customerId|      name|
+----------+----------+
|       105|iteblog003|
|       106|iteblog004|
|       104|iteblog002|
+----------+----------+

同様に、LEFT ANTIJOINもNOTINで書き換えることができます。


scala> val r = spark.sql("select * from customer where customerId not in (select customerId from order)")
r: org.apache.spark.sql.DataFrame = [customerId: int, name: string]
scala> r.show
+----------+----------+
|customerId|      name|
+----------+----------+
|       104|iteblog002|
|       105|iteblog003|
|       106|iteblog004|
+----------+----------+

LEFT SEMI ANTIは、次の図で表すことができます。

ApacheSparkでサポートされている7つの結合タイプの概要

さて、Sparkの7つの結合タイプが簡単に紹介されました。さまざまなタイプのビジネスシナリオに応じて、さまざまな結合タイプを選択できます。今日はこれでおしまいです。ご清聴ありがとうございました。

おすすめ

転載: blog.51cto.com/15127589/2678048