// 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));
3 回答
UPDATE :现在有doc on structuring data . 另外,请参阅NoSQL data structures上的这篇优秀文章 .
与RDBMS相反,分层数据的主要问题在于,因为我们可以嵌套数据很有诱惑力 . 通常,您希望在某种程度上规范化数据(就像使用SQL一样),尽管缺少连接语句和查询 .
您还希望在有效读取效率的地方使用denormalize . 这是所有大型应用程序(例如Twitter和Facebook)使用的技术,虽然它违反了我们的DRY原则,但它通常是可扩展应用程序的必要功能 .
这里的要点是你想要努力写作以使阅读变得容易 . 保持单独读取的逻辑组件(例如,对于聊天室,如果您希望以后能够迭代组,请不要将消息,关于房间的元信息和成员列表放在同一位置) .
Firebase的实时数据和SQL环境之间的主要区别是查询数据 . 没有简单的方法可以说“选择用户在哪里X = Y”,因为数据的实时性(它不断变化,分片,协调等,这需要更简单的内部模型来保持同步的客户端)
一个简单的例子可能会让你处于正确的心态,所以这里有:
现在,由于我们处于分层结构中,如果我想迭代用户的电子邮件地址,我会这样做:
这种方法的问题是我刚刚强迫客户端下载所有用户的
messages
和widgets
. 如果这些东西中没有一个成千上万,那就没什么大不了的 . 但对于拥有超过5k消息的10k用户来说,这是一个大问题 .所以现在,分层实时结构的最佳策略变得更加明显:
在这种环境中非常有用的另一个工具是索引 . 通过创建具有某些属性的用户索引,我可以通过简单地迭代索引来快速模拟SQL查询:
现在,如果我想要获取gmail用户的消息,我可以这样做:
我在另一篇关于非规范化数据的SO帖子中提供了一些细节,so check those out as well . 我看到弗兰克已经发布了Anant 's article, so I won't重申这里,但这也是一个很好的阅读 .
Firebase非常不像关系数据库 . 如果你想将它与任何东西进行比较,我会将它与分层数据库进行比较 .
Anant最近在Firebase博客上撰写了一篇关于非正规化数据的精彩帖子:https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html
我确实建议将每个申请的“身份证”保留为每个申请人的子女 .
您的场景在关系世界中看起来像一对一,根据您的示例,申请人有许多应用程序 . 如果我们来firebase nosql方式它看起来像下面 . 它应该可以扩展任何性能问题 . 这就是为什么我们需要如下所述的非规范化 .