プログラミング個人開発でFirestoreを使っているので情報を集めている。Blogでしっかり書いてあったfirebase.googleblog.comFirestoreなどのNoSQLデータベースは前提として非正規化(denormalization)してサブコレクションをつくることでデータの関連を表現することが推奨されている。Group)という機能を使うことで正規化したデータのようにサブコレクションを扱うことできる。実際の例たとえば「Firestoreで食べログ的なアプリケーションを作る」というケースでは単純に考えてRestaurantコレクション配下に、そのレストランについているレビューのデータを表現するReviewコレクションが存在する、ということは容易に想像できる。このデータ設計では、ある特定のレストランのレビュー一覧を取得することは簡単であるが、もしレストラン関係なくデータとして存在するすべてのレビューを横断して取得したい、というユースケースの際には困ることになる。雑にやるとしたら、まずはレストランの一覧を取得した上で、こんどはレストラン毎にレビューの一覧を取得するという、どう考えてもN+1にしかならない処理をしなくてはいけなくなる。それどころか「全てのレビューから日付が昨日以前のものだけクエリしたい」や「ある特定のユーザーが書いているレビューのみだけクエリしたい」というケースの場合にも一旦すべてのデータを取得せなばならず、どう考えてもオーバーヘッドと金がかかる処理にならざるをえない。コレクション・グループによる解決つまり、これを解決するのがコレクショングループである。非正規化されているデータであっても、インデクスが貼ってあればまるで正規化されたRDBMSでJOINするかのようにデータをクエリすることができる。メソッドを使ってログに出てくる警告メッセージからオンデマンドでインデクスをFirestoreに作らせる方法があるとのこと。最後に、注意点として記載されていたがコレクション・グループでは異なるコレクション配下であるとしても重複したサブコレクション名を許容できないとのこと。RestraurantコレクションとCouriersコレクションそれぞれにサブコレクションとしてReviewsというものがあると、それらは個別のものとしてみなされないらしい。解決策としてコレクションの名前にユニークなプレフィクスを付ける(たとえばCourierReviews的な)というものがあるらしいが、これは早めに気づいておかないと大きな問題になる気がする。おもしろかったFAQとして「Firestoreのデータ構造もRDBMSのように正規化してトップレベルにRestraurantやReviewのようなコレクションを配置して毎回クエリで絞りこめばいいのにコレクション・グループを推す意味はなんなのか」というものがあり、コレに対する答えとしてFirestoreはパフォーマンス上の制約からカスタムインデクス*2が最大で200個までしか許容されていないという仕様が上げられている。Firestoreでデータを正規化するのか、しないのかの議論は個別のユースケースによるものであるので、一概に絶対に非正規化することが常に正しい言い切れないが。Kindle版この商品を含むブログを見る*1:NoSQLはパフォーマンスを重視して作られているためJOINの概念がない、そもそもRDBMSの補助を期待して作られているので正規化したデータはRDBMSに置けばよい、など*2:正規化したコレクションに貼る外部キーへのインデクス。Firestoreではインデクスが貼られていないとクエリの対象にできない。先日業務で1からElmアプリケーションを作りきったのでそのとき...2019-03-23社会人エンジニアに求められたもの去年の4月から社会人としてエンジニアをやっている。(8)はてなブログをはじめよう!IzumiSyさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。