我正在研究一种非常简单的类似电子邮件的消息功能,作为App Engine应用程序的一部分。它比电子邮件更简单,因为没有“主题行”。换句话说,两个用户(或更多,但不是数百)可以在包含所有来回消息(如IM,但是在会话之间持续存在的线程)的对话线程中交换消息。到目前为止,我想这种建模两种类型的实体:消息与对话App Engine中的简单消息传递模型
class Message(db.Model):
sender = StringProperty(required=True)
receiver = StringProperty(required=True)
message = TextProperty(required=True)
timestamp = DateTimeProperty(auto_now_add=True)
class Conversation(db.Model):
messages = ListProperty(int) # List holding the datastore-assigned integer ids of the messages in this conversation
users = StringListProperty()
由于制作消息需要一个会话的创建或修改,我想用来存储信息和会话在同一实体组,以便这些更改可以发生在事务中。我想我会将消息实体作为其关联对话实体的子对象。
消息需要对话实体将其指定为父对象的键。对话需要消息的ID将其存储在消息属性中。
什么是最有效的方法来做到这一点?
- 如果我有数据存储分配一个ID为对话的实体,那么我需要(1)把谈话实体到数据存储,以获取其ID,(2)把消息实体到数据存储得到其ID,以及(3)更新Conversation实体以添加新的消息ID并将其重新放入数据存储中。这需要3次访问数据存储,这看起来效率低下。
- 我也可以为Conversation实体创建一个唯一的键名(例如,';'。join(sorted(conv.users))。通过这样做,我可以避免上面列出的三个数据存储之一。
有没有办法用一个单趟到数据存储做到这一点?我担心边际量的效率,这是我应该真的不担心?是有什么我一个聪明的设计模式如果是这样,我会非常欣赏一个指针
感谢您的回复。在Conversation实体中存储消息列表的原因是避免在对话中检索消息的查询(比向对话添加消息更频繁)。这样,当我需要在特定对话中显示消息时,我只需从消息属性中获取它们的ID并从数据存储中获取它们,而无需执行查询。我知道执行查询所花费的时间要比通过id获取所花费的时间长得多。请帮助我了解我是否没有正确地考虑此问题。 – cv12
我认为关键查询速度快的原因是因为总是有一个索引用于他们。由于你的Message.conversation属性有一个索引,所以我希望查询速度一样快。 – arkanciscan
如果您可以想象会话中有数百条或更多的消息,我强烈建议您使用索引。它为您提供了更灵活的查询功能。假设您只想从对话中获取最近24小时的消息。有了索引,这很容易。使用ID列表,这是不可能的。它也少了RPC。如果您知道对话ID,则可以运行一个查询来撤消关联的消息,而不是一个RPC来获取对话,而另一个RPC获取一批消息。 –