uwu

プログラミングの備忘録を書いています。誰かの為になれば幸いです

Firestore Cloud firestoreの公式動画まとめ4

前回の記事の続きです。
今回はマップ、配列、サブコレクションについてのお話です。
早速みていきましょう!!


www.youtube.com
※この記事で使われている全ての画像はこの動画内から切り抜いたものです。


はじめに

マップ、配列、サブコレクションの違いについて知る前に、
Firestoreでベストなデータ構造を決定するための、データ構造の心構えを知っていきましょう。




心構え1.ドキュメントにはリミットがある




ドキュメントにはどのくらいデータを入れれるかのリミットがあります。




・1ドキュメント1メガまで
これはハイクオリティの画像データを保存するには少ないが、文字列や数値を保存するには十分な数値です。
・2万個以上のフィールドを持つことはできない
マップ内のフィールドも1つのフィールドとしてカウントされます。
以下はフィールド数7とカウントされます。






この制限の理由はFirestoreがドキュメントのすべてのフィールド(マップ含む)にインデックスを作成するため




・同一のドキュメントに対しては、通常1秒間に1回の書き込みに制限される
・多くのクライアントが同じドキュメントに一斉に書き込みをしようとすると、書き込みに失敗することがある(コレクション内の異なるドキュメントに書き込むことは問題ない)




心構え2.ドキュメントを部分的に取得することはできない




ドキュメントには莫大なデータを置くことができるが、おすすめはしない。
なぜなら、Firestoreがドキュメントを取得する時、全てのデータも取得するからです。
そして、部分的に文字を取り出すといったことはできません。




読み取る必要がない巨大なフィールドを格納していると、
不要な読み取りが発生し、モバイルのバッテリー容量の消費やパフォーマンスの低下につながります。
また、ドキュメントの一部にのみセキュリティルールを適用することはできません。




心構え3.クエリは浅い




・ドキュメントを取得するとき、サブコレクションの中のデータは取得されない


dickens_booksのタイトルを取得したい場合、サブコレクションであるchaptersは取得されません。





心構え4.読み書きの回数によって料金が発生する



もしドキュメントの中のサブコレクションをわけた場合、
サブコレクションの中のドキュメントが欲しいなら読み取り回数が増えることになる







心構え5.配列が変



配列はFirestoreで時に上手く機能しません。

// 下記の配列をFirebaseに送ったら
['a', 'b', 'c', 'd', 'e']
// Firebaseは下記のようにデータを保存します
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}

// keyが一連の数字であるため
// クエリを行うと下記のデータが返ってきます
['a', 'b', 'c', 'd', 'e']

// しかしa, b, dを削除したら
// 配列のkeyが一連の数字ではなくなります
// この為Firebaseは下記を返し、配列を返さなくなります
{2: 'c', 4: 'e'}


もっと詳しい説明はこちらから:
Best Practices: Arrays in Firebase




そして、たくさんのクライエントが同じ配列の操作を行う場合、容易く混乱が起きます。




まずはマップの例を見ていきましょう。
このようにマップのフィールドを違う人がそれぞれ更新したり削除したりするのは問題なく行えます。





しかし、配列を違う人がそれぞれ更新したり削除したりすると予期せぬデータが返ってきたり
エラーになったりします。これらの命令をどの順番で受け取るかによって、結果は大きく異なります。





このようにkeyを指定して値を変更したり削除したりすることもできません。





こうなってくると、配列が必要ないかのように見えますがそうではありません。




以下の本のDBの例を見てみましょう。
キーワードがdramaになっている本を探したいとします。






Firestoreの中ではこの配列をこのようなマップに置換しています。





マップにはインデックがつくので、keywords.drama == trueでdramaというキーワードの本が探せる、という仕組みです。


結局どうするのがいいの?


・大きくしすぎると不要な読み取りが発生し、小さくサブコレクションでわけすぎると読み取り回数が増えるので、ちょうどいいサイズを目指すこと。


・もしいつも取得したいデータがある場合は
データをトップレベルのドキュメントに全て保存するといい。


・データをサブコレクションに入れるときは
それぞれのデータを検索したいとき、またはデータ(key:value;)が今後肥大しそうな時にするといい。


・コレクションの中のデータをベースに検索したいならマップを使うといい。


・マップはデータを整理整頓をしたい時にも使うといい。
マップにすることで今後命名が競合するリスクも防げる。


・flag管理するためには配列を使うといい。







5へ続きます!