我正在开发一个非常简单的类似电子邮件的消息传递功能,作为App Engine应用程序的一部分。它比电子邮件更简单,因为没有“主题行”。换句话说,两个用户(或更多,但不是数百个)可以在对话线程中交换消息,该对话线程包含所有来回消息(如IM,但会话之间存在持续的线程)。到目前为止,我正在考虑使用两种类型的实体对其进行建模:消息和对话
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()
由于创建Message需要创建或修改Conversation,我希望将Message和Conversation存储在同一个实体组中,以便这些更改可以在事务中发生。我想我会将Message实体作为其关联的Conversation实体的子节点。
Message需要Conversation实体的密钥才能将其指定为父级。 Conversation需要Message的id将它存储在messages属性中。
最有效的方法是什么?
有没有办法通过一次访问数据存储区来完成此操作?我担心边际效率,我真的不担心吗?对于我想要做的事情,是否有更智能的设计模式?如果是这样,我真的很感激指针。
答案 0 :(得分:4)
您正在颠覆传统的设计模式,即:
class Conversation(db.Model):
users = StringListProperty()
class Message(db.Model):
sender = StringProperty(required=True)
receiver = StringProperty(required=True)
message = TextProperty(required=True)
timestamp = DateTimeProperty(auto_now_add=True)
conversation = db.ReferenceProperty(Conversation)
在上面的模型中,除非您要更新用户列表,否则在存储新邮件时不需要修改对话实体。我建议使用此项,除非有理由不这样做。
这也应该更具可扩展性。如果您的对话达到1000条消息,则您不必在单个对话实体上存储1000条消息ID属性。
但是,我们假设您要保留原始模型。要在一次旅行中存储对话和消息,您需要急切地分配消息ID。我的建议是生成一个UUID(例如,使用uuid.uuid4()
)并将其指定为消息密钥名称(并将其附加到消息列表),而不是等待数据存储区分配ID。