119

私はfirebaseを初めて使用し、データを構造化する最良の方法を知りたいです。

簡単な例があります:

私のプロジェクトには申請者とアプリケーションがあります。1 人の申請者が複数の申請を行うことができます。この2つのオブジェクトをfirebaseに関連付けるにはどうすればよいですか? リレーショナル データベースのように機能しますか? それとも、データ設計の観点からアプローチを完全に変える必要がありますか?

4

3 に答える 3

150

更新:データの構造化に関するドキュメントが作成されました。また、 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。それらの数が何千にもならなければ大したことではありません。しかし、それぞれ 5,000 件以上のメッセージを持つ 10,000 人のユーザーにとっては大したことではありません。

したがって、階層的なリアルタイム構造の最適な戦略がより明確になります。

/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 投稿で詳細を提供したので、それらもチェックしてください。Frank はすでに Anant の記事を投稿しているようなので、ここでは繰り返しませんが、これも素晴らしい読み物です。

于 2013-05-07T15:47:24.767 に答える
50

Firebase はリレーショナル データベースとはまったく異なります。何かと比較したい場合は、階層型データベースと比較します。

Anant は最近、データの非正規化に関する Firebase ブログに素晴らしい記事を書きました: https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html

各アプリケーションの「ID」を各アプリケーションの子として保持することをお勧めします。

于 2013-05-07T15:34:55.550 に答える