goo blog サービス終了のお知らせ 

ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

SQL to AsakusaFW:INSERT

2019-12-07 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2019の7日目、SQLをAsakusaFWに変換するポイントについてです。

SQLのINSERT文は、VALUESを使う構文とSELECTを使う構文があります。

まずINSERT-SELECTですが、これはSELECTした結果をINTOで示されたテーブルに入れるものなので、SELECT文をAsakusaFWに変換するのと同様(出力先データモデルが違うだけ)です。

一方、INSERT-VALUESは入力が何も無い状態からデータを出力することになりますが、AsakusaFWでは入力が無い場合の処理を記述することは出来ません。
core.empty演算子は空のデータを出力しますが、それと似て1レコードだけ出力するcore.oneみたいな演算子が欲しいなーと思っているのですが^^;)
ただ、ダミーで1レコードだけ存在しているファイルをジョブフローの入力とし、それをExtract演算子に渡せば、Extract演算子は自由に複数レコード出力することが出来るので、INSERT-VALUESを実現できます。


それと、テーブル定義のデフォルト値の仕組みはAsakusaFWには無いので、VALUESで指定されていない項目に対するデフォルト値は自分でセットする必要があります。
これは簡単だから特に問題ないのですが、問題は、IDの自動採番の仕組みです。

AsakusaFWは分散して処理するので、全体を通して一意になる値を採番することは出来ません。
処理を行うサーバーのホスト名やUUIDなんかを組み合わせれば一意にすることは出来ますが、RDBの自動採番はほぼ数値なので、直接的な代替にはなりませんよね…。
なので、Oracle用ですが、そこだけJDBC接続してOracleのシーケンスで採番するユーティリティーを作ってみました。


SQL to AsakusaFW:DELETE

2019-12-06 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2019の6日目、SQLをAsakusaFWに変換するポイントについてです。

SQLのDELETE文を考えてみましょう。
WHERE条件が無いDELETE文の場合、全件削除となります。AsakusaFWでは、入力データをcore.stop演算子に渡し、core.empty演算子で空データを出力するのが良さそうです。
というか、ただ単に何もしないということなので、わざわざAsakusaバッチにする必要は全く無いですね(爆)

WHERE条件が有るDELETE文の場合、Branch演算子で条件分岐し、削除する側をcore.stop演算子に渡すことになるでしょう。


ひとつ問題となるのは、RDBへの反映方法です。
たいていのRDBを扱うAsakusaバッチの場合、出力結果をRDBに反映することになると思います。

INSERTやUPDATEの場合は出力したデータをテーブルに反映(上書き)すればいいですが、DELETEではそういうわけにいきません。RDB上の既存データと比較して存在チェックをし、無いものを実際にDELETEすることになりそうですが、面倒ですよね…。

削除したデータをcore.stop演算子に渡すのではなく削除済みデータとして出力しておけば、そのプライマリキーを元に(AsakusaFW以外のツールで)DELETE文を発行するという方法が使えます。こちらの方が幾分簡単な気がします。

なお、AsakusaFWのWindGate JDBCを使っている場合は、RDBへの反映はTRUNCATE(全件削除)+全件INSERTなので、DELETEだからと言っても特別な考慮をする必要はありません。


SQL to AsakusaFW:UPDATE

2019-12-05 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2019の5日目、SQLをAsakusaFWに変換するポイントについてです。

SQLのUPDATE文はテーブルの(一部の)カラムを更新するので、AsakusaFWのUpdate演算子で実現できます。
別テーブルのデータを用いて更新する場合は、CoGroup演算子等で結合して更新します。

あと、RDBMSのトリガーのような機能はAsakusaFWには無いので、必要であれば別途コーディングする必要があります。


SQL to AsakusaFW:SELECT

2019-12-04 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2019の4日目、SQLをAsakusaFWに変換するポイントについてです。

SQLで最も使われるのはSELECT文だと思います。
SELECT文ではテーブルの結合やWHERE条件・集約など色々なことが出来ますが、それは後日取り上げるとして、今日はSELECT句に絞ります。
SELECT句とは「SELECT col1, col2, …」という部分のことです。

AsakusaFWに変換するときは、SELECTする項目だけを表すデータモデルを作って出力する形になるでしょう。
FROM句(あるいは集約の場合は集約結果)を表すデータモデルから、SELECT句で出力する項目の演算を行って出力します。
これにはAsakusaFWのConvert演算子がぴったりです。


SQL to AsakusaFW:テーブル

2019-12-03 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2019の3日目、SQLをAsakusaFWに変換するポイントについてです。

SQLをAsakusaFWに変換するに当たって、まず必要なのはテーブルですね。
AsakusaFWでテーブルに相当するのはデータモデルです。
元々AsakusaFWはWindGate JDBCでテーブルをデータモデルとして読み書きすることができるので、それに準じます。

RDBの基本的なデータ型はAsakusaFWのDMDLデータ型に対応するものがありますが、TIMESTAMP(秒より小さい単位、すなわちミリ秒やマイクロ秒)に直接対応するデータ型はAsakusaFWには無いので、必要であればTEXT等で代用することになります。

BLOB等のバイナリーや配列(ARRAY)は使えません。
もし配列を使いたいなら、JSONにでもして、TEXTとして保持するとか…?

また、AsakusaFWに制約(NOT NULLやUNIQUE等)の機構はありません。
必要であれば、そのチェックロジックを自分でコーディングする必要があります。

テーブル(データモデル)の結合にはAsakusaFWを実行する基盤(SparkM3BP)のシャッフル機能を使うので、テーブルのインデックスは必要ありません(インデックスのような仕組みはありません)。