我设计数据存储的背景来自iOS上的Core Data,它支持与另一个实体具有一对多关系的属性。
我正在开发一个目前有三种实体类型的App Engine项目:
User
,代表使用该应用的人。Project
,代表一个项目。 User
可能与许多项目相关联。Post
,这是Project
背后的主要内容。 Project
可能有很多帖子。 目前,User
有一个属性projects
,它与Project
个实体的一对多关系。 Project
有一个属性posts
,它是与Post
个实体的一对多关系。
在这种情况下,数据存储区的参考属性或NDB的结构化属性更适合作业(两者在概念上有何不同)?有没有更好的方法来构建我的数据?
答案 0 :(得分:11)
通过引用属性,您可能意味着Key Property。这是对另一个数据存储区实体的引用。它存在于db和ndb API中。使用这些,您可以通过将许多实体指向另一个实体的键来建模多对一关系。
结构性属性是一种完全不同的野兽。它允许您定义数据结构,然后将其包含在另一个实体中。
以下是您为单个联系人提供多个地址的文档示例:
class Address(ndb.Model):
type = ndb.StringProperty() # E.g., 'home', 'work'
street = ndb.StringProperty()
city = ndb.StringProperty()
class Contact(ndb.Model):
name = ndb.StringProperty()
addresses = ndb.StructuredProperty(Address, repeated=True)
guido = Contact(name='Guido',
addresses=[Address(type='home',
city='Amsterdam'),
Address(type='work',
street='Spear St',
city='SF')])
guido.put()
对于您的特定应用,我建议使用NDB(最好使用最新版本的api),具体如下:
将项目模型中包含的模型作为重复的结构化属性。 用户包括重复的KeyProperty,其中包含他们有权访问的项目的键。
为了使它更复杂,您可以创建另一个模型来表示项目和权限/角色,然后将其包含在用户模型中作为重复的结构化属性。
您希望坚持使用密钥的主要原因是根据HRD最终的一致性来保持数据的可访问性。
如果您需要更多帮助,请与我们联系。
编辑:
澄清一下,这是建议的结构:
型号:
用户模型应包含User-Project-Mapping作为重复的结构化属性。
项目模型应包含Post作为重复的结构化属性。
User-Project-Mapping只需要包含对项目和相关权限表示的Key引用。
由于这听起来像是一个商业项目,如果你想进一步帮助我,我很乐意为你咨询。希望你有足够的成功!
答案 1 :(得分:3)
还有另一点没有提到并且可能是相关的:插入 StructuredProperty 中的实体不是完整的实体“,如this part of the docs中所述。以下是完整的引用(它指的是@Sologoub在答案中提到的相同示例):
尽管使用相同的地址实例定义了地址实例 语法和模型类一样,它们不是完整的实体。他们 在数据存储区中没有自己的密钥。他们无法检索 独立于它们所属的联系实体。
这可能会给设计带来一些限制,因为您不能在不重复数据的情况下重用实体的属性。另一方面, KeyProperty 引用另一个实体的密钥,因此以更“关系”的方式表示实体关系。 KeyProperties 也可以重复:只需添加repeated=True
参数。