如何在Firebase中构建数据以避免N + 1选择? [英] How to structure data in Firebase to avoid N+1 selects?
问题描述
假设您有一个像WhatsApp这样的基本消息应用程序。用户可以与其他用户组打开聊天,在他们之间发送私人消息。以下是我如何在Firebase中组织的最初想法(有点类似于):
{
users:{$ rel =nofollow> b $ b $ uid:{
name:string,
chats:{
$ chat_uid:true,
$ chat2_uid:true
}
}
},
聊天:{
$ uid:{
messages:{
message1:'first message',
message2:'another message'
$ b $ / code $ / pre
$ b Firebase权限可以设置为只允许用户读取在其用户对象中标记为 true
的 chats
(并限制任意添加到 chats
object等)。
然而这个布局需要N + 1个选择几个常见的情况。例如:要构建主屏幕,应用程序必须先检索用户的 chats
对象,然后制作 get
请求每个线程获取其信息。同样的事情,如果用户想要搜索他们的对话特定的字符串:应用程序必须运行一个单独的请求,每个聊天他们有权访问,以查看是否匹配。
我很想设置一个node.js服务器来针对 chats
树运行根认证的查询,并完全跳过客户端的firebase代码。但是这首先破坏了Firebase的用途。
有没有办法像使用Firebase权限一样组织这样的数据,并避免N + 1选择问题?
p>
解决方案似乎并不一定需要避免n + 1个查询,并且Firebase专门设计为在执行n +1选择,尽管对于来自关系数据库背景的开发人员来说是违反直觉的。
Firebase 2.4.2文档后面有一个令人欣慰的消息:
//列出所有Mary的组名
var ref = new Firebase(https://docs-examples.firebaseio.com/web/org );
$ b $ //获取Mary's组的列表
ref.child(users / mchen / groups)。on('child_added',function(snapshot){
//为每个组获取名称并打印它
String groupKey = snapshot.key();
ref.child(groups /+ groupKey +/name\").once('value',函数(快照){
System.out.println(Mary是这个组的成员:+ snapshot.val());
});
});
单独查找每个记录真的可以吗?是。 Firebase协议使用Web套接字,客户端库对传入和传出的请求进行了大量的内部优化。在获得数万条记录之前,这种方法是完全合理的。实际上,下载数据所需的时间(即字节数)使连接开销的任何其他问题重演。
Since Firebase security rules cannot be used to filter children, what's the best way to structure data for efficient queries in a basic multi-user application? I've read through several guides, but they seem to break down when scaled past the examples given.
Say you have a basic messaging application like WhatsApp. Users can open chats with other groups of users to send private messages between themselves. Here's my initial idea of how this could be organized in Firebase (a bit similar to this example from the docs):
{
users: {
$uid: {
name: string,
chats: {
$chat_uid : true,
$chat2_uid: true
}
}
},
chats: {
$uid: {
messages: {
message1: 'first message',
message2: 'another message'
}
}
}
}
Firebase permissions could be set up to only let users read chats
that are marked true
in their user object (and restrict adding arbitrarily to the chats
object, etc).
However this layout requires N+1 selects for several common scenarios. For example: to build the home screen, the app has to first retrieve the user's chats
object, then make a get
request for each thread to get its info. Same thing if a user wants to search their conversations for a specific string: the app has to run a separate request for every chat they have access to in order to see if it matches.
I'm tempted to set up a node.js server to run root-authenticated queries against the chats
tree and skip the client-side firebase code altogether. But that's defeating the purpose of Firebase in the first place.
Is there a way to organize data like this using Firebase permissions and avoid the N+1 select problem?
解决方案 It appears that n+1 queries do not necessarily need to be avoided and that Firebase is engineered specifically to offer good performance when doing n+1 selects, despite being counter-intuitive for developers coming from a relational database background.
An example of n+1 in the Firebase 2.4.2 documentation is followed by a reassuring message:
// List the names of all Mary's groups
var ref = new Firebase("https://docs-examples.firebaseio.com/web/org");
// fetch a list of Mary's groups
ref.child("users/mchen/groups").on('child_added', function(snapshot) {
// for each group, fetch the name and print it
String groupKey = snapshot.key();
ref.child("groups/" + groupKey + "/name").once('value', function(snapshot) {
System.out.println("Mary is a member of this group: " + snapshot.val());
});
});
Is it really okay to look up each record individually? Yes. The Firebase protocol uses web sockets, and the client libraries do a great deal of internal optimization of incoming and outgoing requests. Until we get into tens of thousands of records, this approach is perfectly reasonable. In fact, the time required to download the data (i.e. the byte count) eclipses any other concerns regarding connection overhead.
这篇关于如何在Firebase中构建数据以避免N + 1选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!