4
5

More than 5 years have passed since last update.

bigqueryにおけるスキーマ管理の悩みとUNIONの性質について

Posted at

まず、結論を先に書いておくと、全然解決してなくて、今も絶賛悩み中です。

bigqueryにデータをロードする時、1テーブルに全データを投入し続けていくと1クエリで読み込むデータがどんどん大きくなり課金額が上がってしまう。(bigqueryはWHERE句等に関わらず常にテーブルの全行を読み込む)
なので、日付毎や何らかのキー毎にテーブルを分けるというのが割と良くあるユースケースになっている。
それを支援するために、テーブルワイルドカード関数が用意されていたり、テーブルのUNIONが,で区切るだけで記述できたりする。

最初勘違いがあったのだが、bigqueryはテーブルレベルでスキーマが異なっていても、クエリで利用するカラム名と型が一致していればUNIONできるという性質を持っている。
まあ、よくよく考えれば当たり前で、普通のRDBでUNION句を利用しても同じことなのだが、bigqueryのクエリ記述上、テーブルワイルド関数とか,区切りのUNIONで、あんまりそれが可能なように見えなかった。

SELECT id, user_id FROM TABLE_DATE_RANGE(dataset.post, TIMESTAMP('2016-1-1'), TIMESTAMP('2016-1-15'))

こういうクエリの時に、post20160110辺りからスキーマが変更されていても、クエリで利用しているカラムさえ一致していれば問題無い。
まあ、当たり前っちゃ当たり前である。

ちなみに、もしカラムを減らす場合にはignoreUnknownValuesを付けておかないと、既存の余計なカラムを含んだデータをそのまま送っているとエラーになる。

問題はカラムを増やした場合の過去データの扱いである。
過去のデータ量が大量になってくるとデータを入れ直すってのは、かなり辛い仕事になりそうだ。
やるにしても、一回GCSにextractしてembulkか何かで加工しながらbigqueryに戻すって感じになるんだろうか。

後考え付くのが、テーブルを別テーブルにCOPYしてオリジナルを削除し、同じ名前でViewを作り直すという方法。
Viewの作成とCOPYジョブは割とすぐ終わるので、API叩くスクリプトを書けばそこそこの時間で終えられそう。
お金もかからない。
問題は、変更が積み重なってくるとViewの編集が辛くなりそうっていう点か。

そもそも、そんな事をするぐらいなら最初から投入後のデータを直で使うのではなく、一回Viewでラップしておくのが良いのではという気もする。見た感じのテーブル量が倍になってしまうが、将来的にカラムが増えたり減ったりした時も、クエリ文字列の編集だけでとりあえず乗り切れる気がする。
(今更そんな感じにするのはちょっと面倒なのだが……。)

もしかしたら、bigqueryはガンガンViewを活用していくのが正解なのかもしれない。
とりあえず、あるテーブルを別名のテーブルに退避して、ビューに差し替えるってのは使い道がありそうな気がする。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5