【发布时间】:2016-06-04 09:07:59
【问题描述】:
假设我正在尝试构建一个群消息应用程序,因此我将数据库结构设计为如下所示:
users: {
uid1: { //A user id using push()
username: "user1"
email: "aaa@bbb.ccc"
timestampJoined: 18594659346
groups: {
gid1: true,
gid3: true
}
}
uid2: {
username: "user2"
email: "ddd@eee.fff"
timestampJoined: 34598263402
groups: {
gid1: true,
gid5: true
}
}
....
}
groups: {
gid1: { //A group id using push()
name: "group1"
users: {
uid1: true,
uid2: true
}
}
gid2: {
name: "group2"
users: {
uid5: true,
uid7: true,
uid80: true
}
}
...
}
messages: {
gid1: {
mid1: { //A message id using push()
sender: uid1
message: "hello"
timestamp: 12839617675
}
mid2: {
sender: uid2
message: "welcome"
timestamp: 39653027465
}
...
}
...
}
根据 Firebase 的文档,这会很好地扩展。
现在假设在我的应用程序中,我想在每条消息上显示发件人的用户名。
查询每条消息的用户名显然很糟糕,所以我发现的解决方案之一是在每条消息中复制用户名。
消息节点现在看起来像这样:
messages: {
gid1: {
mid1: { //A message id using push()
sender: uid1
username: "user1"
message: "hello"
timestamp: 12839617675
}
mid2: {
sender: uid2
username: "user2"
message: "welcome"
timestamp: 39653027465
}
...
}
...
}
现在我想为用户添加更改用户名的选项。
因此,如果用户决定更改他的用户名,则必须在用户节点以及他发送的每条消息中进行更新。
如果我采用“每条消息的侦听器”方法,那么更改用户名会很容易,因为我需要在一个位置更改名称。
现在,我还必须更新他发送的每个组的每条消息中的名称。
我认为查询整个消息节点以获取用户 ID 是一个糟糕的设计,因此我考虑创建另一个节点来存储用户发送的所有消息的位置。
它看起来像这样:
userMessages: {
uid1: {
gid1: {
mid1: true
}
gid3: {
mid6: true,
mid12: true
}
...
}
uid2: {
gid1: {
mid2: true
}
gid5: {
mid13: true,
mid25: true
}
...
}
...
}
所以现在我可以快速获取特定用户的所有消息的位置,并通过一次 updateChildren() 调用更新用户名。
这真的是最好的方法吗?我真的需要复制这么多数据(数百万条消息),只是因为我引用了一个动态值(用户名)吗?
或者在处理动态数据时有更好的方法吗?
【问题讨论】:
-
已经有很多好的答案了。我将链接到我不久前写的关于如何编写扇出/非规范化数据的答案,以防您选择该路线:stackoverflow.com/questions/30693785/…
标签: firebase firebase-realtime-database