概要
実務でFirestoreを使ったので良かった点不便だった点を書いていきます。
ご指摘などあればコメントいただけると幸いです。
メリット
スケール/インフラ
FiresoreはJOINを前提としないドキュメントモデルのためをデータを分散しやすい。
その結果、RDBのような垂直スケールの運用をせず、スケーラビリティを強く意識せずに運用することができる。
また、フルマネージドであるので、インフラの運用やクラウド側に任せ、アプリケーション設計に集中できる。
レプリケーション
複数ゾーン/リージョンにリプリケーションされているので1つのデータセンターが使用できなくともサービスは継続できる。
セキュリティルール
セキュリティルールを使って、ユーザー単位のアクセス制御を行えるため簡単にDBのセキュリティを向上させることができる。
また、Authやセキュリティルールを使用すると、APIを立てずにWeb/モバイルから直接アクセスすることができるのでスタートアップなどのスピード重視の組織に向いている。
リアルタイム同期
onSnapshot() メソッドを使用すると内部的にWebSocketを使用して、簡単にフロントからリアルタイム同期をすることができる。
スキーマレス
スキーマレスデータベースであるため、データを柔軟に変更することができる。
そのため、仕様変更に強くスピード感の必要な開発に向いている。
トランザクションの楽観ロック
データをロックしないので並列に実行することができ、多くの読み取りに対応できるため速度を落とさずに処理することができる。
また、Firestoreのようにデータが分散されて管理されている場合、ロックの有無を確認するのにネットワーク通信が必要になるが、それが無いので処理速度が速くなる。
デメリット
複雑なデータを取得・表現することが難しい
スケーラブルなデータベースにする思想で作られており、ドキュメント同士がリレーションを持たない設計のため複数のドキュメントが必要な複雑なデータを取得することが難しい。
仮に、userドキュメントとorderドキュメントが存在している場合、userドキュメントを取得して、orderドキュメントのuserIDフィールドをwhereで指定して取得し、アプリケーション側で紐付けることになるが、これが大規模で複雑になるとクエリ設計やアプリケーション側の実装に時間がかかる。
また、集計なども苦手なためBigQueryなどと連携して弱点を補う必要がある。
複合インデックスの上限
クエリ設計を考える際にしっかり考えるようになるメリットもあるが、リレーショナルなデータ構造をFirestoreで扱う場合、この上限がネックとなり複雑なクエリを書くことができなくなってしまう。
上限を気にして必要なインデックスも貼れなくなり、簡単なwhereだけ指定してアプリケーション側でフィルターするようなコーディングになることもあり、コード量が増える。
複雑なクエリが書けない
OR 条件の最大個数が決まっていたりなど複雑なクエリが書けない仕様になっている。
そのため、複雑なデータ取得をしたい場合はクエリではなくアプリケーション側でフィルタリングしてあげる必要がある。
スキーマレス
スキーマレスゆえ、ドキュメントが古いものと変わっていたり、型が揃っていないなどの無秩序になる可能性がある。
トランザクション
楽観ロックなので、競合が立った場合の処理をアプリケーション側で実装する必要がある、頻繁に変更されるドキュメントの場合retry地獄になってエラーになる可能性がある。
参照
https://firebase.google.com/docs/firestore/understand-reads-writes-scale?hl=ja#data_layout
https://firebase.google.com/docs/firestore/query-data/listen?hl=ja