SparkからJDBC経由でデータロードするときの選択肢は「SQLContext」と「JdbcRDD」の2つがあります。
SQLContextが推薦されてるようで使い方ももっと簡単で使い勝手も良かったですが、それでもJdbcRDDの方が良い場合がありました。
次のSQLContextのJDBCの例ではdbtableにselect文も指定できます。
https://github.com/sujee81/SparkApps/blob/master/spark-load-from-db/src/main/java/com/sparkexpert/Main.java
ですが「(select emp_no, concat_ws(' ', first_name, last_name) as full_name from employees) as employees_name」のような少し微妙なSQLになっています。
その理由はsql.jdbc.JDBCRDD#resolveTableの"SELECT * FROM $table WHERE 1=0"でMeta情報を取得してるからです。
この場合、dbtableのSQLにGroup byなどは指定出来ません。
しかし「JdbcRDD」は自由にSQLがかけるのでGroup byがかけます。
そもそもSQLでではなくsparkのdataframeのGroupbyを使うべきでしょうという指摘もあるでしょう。
データロードの処理を共通化したり、Prestoなどから集計対象データを絞ったり、整形したりが効率や可読性が良いケースもあると思います。
最後に私の場合は、
1つのデータロード用のオブジェクトにSQLを渡して処理してますが、様々なテーブルのデータ整形をSQLで行った方がわかりやすいと感じてます。
例えば、Aテーブルの場合は Group byが必要、Bテーブルの場合はJOINが必要なケースも柔軟にかけるからです。
SQLContextが推薦されてるようで使い方ももっと簡単で使い勝手も良かったですが、それでもJdbcRDDの方が良い場合がありました。
次のSQLContextのJDBCの例ではdbtableにselect文も指定できます。
https://github.com/sujee81/SparkApps/blob/master/spark-load-from-db/src/main/java/com/sparkexpert/Main.java
ですが「(select emp_no, concat_ws(' ', first_name, last_name) as full_name from employees) as employees_name」のような少し微妙なSQLになっています。
その理由はsql.jdbc.JDBCRDD#resolveTableの"SELECT * FROM $table WHERE 1=0"でMeta情報を取得してるからです。
この場合、dbtableのSQLにGroup byなどは指定出来ません。
しかし「JdbcRDD」は自由にSQLがかけるのでGroup byがかけます。
そもそもSQLでではなくsparkのdataframeのGroupbyを使うべきでしょうという指摘もあるでしょう。
データロードの処理を共通化したり、Prestoなどから集計対象データを絞ったり、整形したりが効率や可読性が良いケースもあると思います。
最後に私の場合は、
1つのデータロード用のオブジェクトにSQLを渡して処理してますが、様々なテーブルのデータ整形をSQLで行った方がわかりやすいと感じてます。
例えば、Aテーブルの場合は Group byが必要、Bテーブルの場合はJOINが必要なケースも柔軟にかけるからです。