存储聊天消息的最简单方法可能是:
message:
-message1 {
"user1"
"user2"
"message"
"date"
}
-message2
-message3
当应用程序增大(大量消息)并且使用.whereEqualTo
完成数据库操作时,以这种方式构造聊天应用程序消息是否有任何缺点?就像数据库遍历所有消息一样?
因为这种方法存在问题,例如,我已经看到了这种结构化数据库的方法,该方法可以将消息隔离在不同的聊天室中
chats: {
-chat1 {
"lastMessage"
"timestamp"
"users": {user1, user2}
}
-chat2
-chat3
}
messages: {
-chat1 {
"message"
"date"
}
}
但是在此示例中,添加新消息将需要用户执行2次写入操作,一次写入新消息,以及一次使用新的chat
和lastMessage
客户端更新timestamp
文档,或添加新消息后,创建云功能以使用新值更新chat
文档。
那么,第一个选项是否有效,还是我应该选择类似第二个示例的内容?
答案 0 :(得分:3)
您提供的第一个选项与在tblMessages
的关系数据库中对此建模的方式非常接近。在NoSQL数据库中,这样的字面翻译很少是您的最佳选择,因为它们的取舍非常不同。例如,您已经注意到需要对两个字段执行查询才能获取两个用户之间的消息。
在NoSQL数据库上对数据建模时,通常建议您在数据库中针对屏幕上看到的内容进行建模。因此,如果您的聊天应用程序具有聊天室的概念(即特定人群之间的持续聊天),我也将在您的数据库中对其进行建模。
在Cloud Firestore中,这意味着您将拥有一个顶级集合,其中每个聊天室都有一个文档,然后在每个此类文档下都有一个子集合,其中包含该聊天室的消息:
ChatRooms (collection)
ChatRoom1 (document)
Messages (collection)
Message1_1 (document)
Message1_2 (document)
ChatRoom2 (document)
Messages (collection)
Message2_1 (document)
Message2_2 (document)
使用此模型,您无需查询即可在聊天室中显示消息,而可以直接从该房间的子集合中加载(全部)消息。它还具有划分房间的优势,这意味着写入可以更好地扩展。
我通常建议在房间里为chat room document IDs after the participants建模,以便您可以轻松地根据参与者来重建ID。但是,对此还有更多有效的选择。