蚊帳の中の日記

ゆるく生きてます

Firebase Realtime DatabaseのデータモデルはデカイJSON

去年モモンガ本を見ながら作った Vue.js + Firebase製のマークダウンエディタを作って、その後もVue.jsの勉強も兼ねてちょっとずつ機能を追加していた。

kayanaka.hatenablog.com

で、「メモにもカテゴリタグ的なもの付けて、それで検索とかもできると便利そう!」と思ったので、データベースにカテゴリカラムを追加しよう!とか思ったのだけど、データを管理しているFirebase Realtime database(以下 realtime)のデータモデルがちょっと余り触ったことない感じで取っ付きにくかったのでメモ。

とりあえずデカイJSON

f:id:kayamelo151515:20190129231639p:plain

公式のドキュメントを見ればわかるのだけど、NoSQLデータベースでredisのようなキーバリュー指向ではなくて、JSONを使った所謂ドキュメント指向的なもの。つまり、でかいJSONになっている。 データ構造もできるだけJSONのネストを深くせず平坦に保つとか、RDBみたいな正規化でなくむしろ非正規化をしてデータを冗長な形にしたほうがフェッチするときに効率的になるとか、色々書いている。 これが普段RDBとか使ってる身としては、結構取っ付きにくかった。realtimeのデータ構造についてググってみると「RDBのようなデータ構造の考え方は一旦忘れたほうがいい」的なことも出てきたりして、普段のDBの扱い方とは勝手が違う。

migrationとかそういうのは無い

で、最初に話していた「カテゴリ機能」を追加したいので、普段Railsに慣れ親しんでいる自分としては「なんかmigration的なことをするのかな?」とか思ってたのだが、実際はそういうことはしない。 クライアント側で、新しくカテゴリのparameterに追加してrealtimeのapiにpostするようにすれば、それ以降に追加したメモにはカテゴリが追加されることになる(こういうデータ構造は多分はスキーマレスDBとか言ったりすると思う)。 それより前に保存されていたメモたちについても、再度保存したタイミングでカテゴリが追加されて更新される。つまり、クライアント側でpostするデータを書き換えれば、それに合わせたデータ構造でレコードも更新してくれるということ。事前にmigration的なことしてデータ定義を設定するという前処理はない。

なんか一つ手間が省けた感があって、いい感じだと思うが以下のような問題も出てくるかなと思う。
例えば、途中でクライアント側からpostするattirbute Aを追加したために、参照しようとしたときにあっちのレコードにはAがあるけど、過去のこっちのレコードにはAがないということが起きたり、途中追加したattributesを使って全データを集計したいとき、そのattributesが無いレコードもあって集計が単純にいかない、とかはありそうだな〜と思った。なので、そのあたりをクライアント側で上手いことしてあげる必要が出てきそう(このあたりは類似形式のDBの特性とか運用方法を勉強すると楽しくなりそう 👨🏼‍💻)。

もしかしたら、FireStoreのほうがいいのかも…

realtime databaseと一緒に似たような Cloud Firestoreってのもあって、こっちはコレクションとかドキュメントという概念でデータを構造化する仕組みになっている。まだ内容をちゃんと読んでないので、よくわかっていないが、もしかしたらrealtime databaseより場合によっては運用がしやすいのかもしれない。こっちも追々触ってみたい。

firebase.google.com


こんな感じで暇な時にVueと一緒にFirebaseでも遊んでいる 🧔