ちょっと未来

ちょっと未来を感じさせるガジェットやアプリ、そして作ったものについて書きます

firestoreを本気で使ってみて知った勘違い3つほど

いまReact Native ✕ firebaseなプロダクトを開発しています。

仕様的にそこまで複雑でなかったので、バックエンドは完全firebaseで作っています。
なのでDBはfirestoreを使っています。

realtime databaseを使ったことはあったけど、firestoreを使うのは初めてです。
というかNo SQL的なのを使うのが初めて。

RDBといろいろ違うってことは分かってたつもりだけど、いざ初めてみると色々な勘違いがありました。

ちなみにfirestoreの勉強は Firestore Mastery - shiodaifuku - BOOTH がめちゃくちゃ為になりました。
チームではバイブル本となっています。

では、勘違いしてたことを3つほど!

何でも非正規化すればよいわけではない

firestoreはRDBとは違って、正規化せずにデータ重複を恐れず非正規化すべき!
という印象が強く、基本的に非正規化するものかと思っていたけど、そういう訳ではないようです。

firestoreの結合は思ったより早く、ケース・バイ・ケースで非正規化するかどうかは判断する必要があります。 そして、バイブル本(上記)によると大半の場合では非正規化をする必要がないとのこと。なんと!

例えば、食べログのようなレビューサイトで、reviewのドキュメントにuser情報を展開するか否かですが、、

  • 画面にレビューを1件だけ表示
    非正規化は不要。1つのuserを結合すればよいだけなので、非正規化せずに都度結合する。

f:id:wasan:20191018215455p:plain

  • レビュー一覧の画面
    非正規化したほうがよさげ。レビュー数だけのuser結合が発生するので、userの名前、アバター画像は非正規化して展開しておくのがよさそう。  

f:id:wasan:20191018215529p:plain

しかし、、、

  • プロフの更新頻度が高い場合
    例えばプロフにScoreという情報があり、1日に10回くらいScoreが更新されるとします。 ある人がレビューを1000件書いてるとすると、毎日1000件x10回のreviewドキュメントの更新が必要になります。 なので、非正規化したデータの更新頻度がめちゃめちゃ高い場合は、非正規化のデメリットも大きくなります。

f:id:wasan:20191018220206p:plain

そのへんのバランスも考慮する必要があり、サービス毎にケース・バイ・ケースで判断が必要になりそうですね。

検索はかなり弱い

firestoreはあまり検索が強くなく、例えば"全文検索"したい場合はalgoliaなどの別の検索サービスを併用するのがよいですよ、っていのは聞いていました。

が、実際使ってみると全文検索の以前に、ORIN での検索もできないんですね。

MySQLの間隔だと当たり前の検索も一筋縄ではいかないようです。

結局ORの絞り込み検索のためにalgoliaを使うことにしました。

他のコレクションへの参照はidでなくreferenceで

RDB的な感覚だと、ほかテーブルのidで参照したりします。 が、firestoreではidではなくreferenceを使いましょう、とのこと。

たぶん基本的なことなんだけど、知らんかった! 先に例のバイブル本を読んでおいてよかったです。

collection groupというもの

これは勘違いというか、こういうものがあると知ったのですが、 collectin groupというものを使うと複数のサブコレクションを横断して検索できます。

具体的に言うと、reviewがrestaurantのサブコレクションとしてに紐付いているとして、、
あるユーザーの投稿したreviewだけを抽出したい場合(マイページとかでありそう)、 restaurant配下を横断して検索できます。

f:id:wasan:20191018222208p:plain

ちなみに、collection groupの登場以前は、あるユーザーの投稿したreviewだけを抽出したい、という要件がある場合は、 reviewはrestaurant配下でなく、まったく別に分けて保持していました。

collection groupの有る無しで、データの設計方法がガラッと変わるので、これは先に知っておいてよかったです。

ちなみにこのcollection groupは今年(2019年)5月に登場したばかりらしいです。
ベストプラクティスもどんどん進化するので、常にキャッチアップが必要ですね〜。