回答:
更新:データの構造化に関するドキュメントがあります。また、NoSQLデータ構造に関するこの優れた投稿もご覧ください。
RDBMSとは対照的に、階層データの主な問題は、データをネストできるため、ネストできることです。一般に、結合ステートメントとクエリがないにもかかわらず、データをある程度(SQLの場合と同じように)正規化する必要があります。
また、読み取り効率が問題となる場所で非正規化する必要があります。これは、すべての大規模アプリ(TwitterやFacebookなど)で使用されている手法であり、DRYの原則に反していますが、一般に、スケーラブルなアプリに必要な機能です。
ここでの要点は、読み取りを容易にするために書き込みに力を入れたいということです。別々に読み取られる論理コンポーネントを別々に保持します(たとえば、チャットルームの場合、メッセージ、ルームに関するメタ情報、およびメンバーのリストをすべて同じ場所に配置しないでください。後でグループを反復できるようにする場合)。
FirebaseのリアルタイムデータとSQL環境の主な違いは、データのクエリです。「SELECT USERS WHERE X = Y」と言う簡単な方法はありません。これは、データのリアルタイム性(データが絶えず変化し、シャーディング、調整などが行われるため、同期クライアントをチェックするためにより単純な内部モデルが必要になるため)です。
簡単な例はおそらく正しい心の状態にあなたを設定するでしょう、それでここに行きます:
/users/uid
/users/uid/email
/users/uid/messages
/users/uid/widgets
さて、階層構造になっているので、ユーザーのメールアドレスを繰り返し処理したい場合は、次のようにします。
// I could also use on('child_added') here to great success
// but this is simpler for an example
firebaseRef.child('users').once('value')
.then(userPathSnapshot => {
userPathSnapshot.forEach(
userSnap => console.log('email', userSnap.val().email)
);
})
.catch(e => console.error(e));
このアプローチの問題は、私はちょうど、ユーザーのすべてをダウンロードするようにクライアントを強制していることであるmessages
とwidgets
、あまりにも。これらの数が数千に数えられなければ、大したことはありません。しかし、1万人以上のユーザーにそれぞれ5000通以上のメッセージを送ることは大きな問題です。
これで、階層的なリアルタイム構造の最適な戦略がより明確になります。
/user_meta/uid/email
/messages/uid/...
/widgets/uid/...
この環境で非常に役立つ追加のツールはインデックスです。特定の属性を持つユーザーのインデックスを作成することで、インデックスを反復するだけでSQLクエリをすばやくシミュレートできます。
/users_with_gmail_accounts/uid/email
たとえば、Gmailユーザーへのメッセージを取得したい場合は、次のようにします。
var ref = firebase.database().ref('users_with_gmail_accounts');
ref.once('value').then(idx_snap => {
idx_snap.forEach(idx_entry => {
let msg = idx_entry.name() + ' has a new message!';
firebase.database().ref('messages').child(idx_entry.name())
.on(
'child_added',
ss => console.log(msg, ss.key);
);
});
})
.catch(e => console.error(e));
データの非正規化に関する別のSOの投稿でいくつかの詳細を提供したので、それらも確認してください。フランクはすでにAnantの記事を投稿しているので、ここでは繰り返し説明しませんが、それも素晴らしい読み物です。
Firebaseはあまりありません、リレーショナルデータベースのように。何かと比較したい場合は、階層型データベースと比較します。
Anantは最近、データの非正規化についてFirebaseブログに投稿しました:https : //www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html
確かに、各アプリケーションの「ID」を各アプリケーションの子として保持することをお勧めします。
あなたの例では申請者が多くのアプリケーションを持っているので、あなたのシナリオはリレーショナルの世界では1対多のように見えます。firebase nosqlを使用すると、以下のようになります。パフォーマンスの問題なしに拡張できます。そのため、以下に述べるように非正規化が必要です。
applicants:{
applicant1:{
.
.
applications:{
application1:true,
application3:true
}
},
applicant2:{
.
.
applications:{
application2:true,
application4:true
}
}}
applications:{
application1:{
.
.
},
application2:{
.
.
},
application3:{
.
.
},
application4:{
.
.
}}