ndb建模一对多:重复KeyProperty与外键的优点

Emi*_* vl 14 google-app-engine app-engine-ndb

我的问题是关于在ndb中建模一对多关系.我知道这可以(至少)以两种不同的方式完成:使用重复属性或使用"外键".我在下面创建了一个小例子.基本上我们有一篇文章可以有任意数量的标签.我们假设可以删除标记,但添加标记后无法更改.我们还假设我们不担心交易安全.

我的问题是:建模这些关系的首选方式是什么?

我的考虑:

  • 方法(A)要求为每个标签添加两个写入(一个用于文章,一个用于标签),而方法(B)只需要一个写入(只有标签).
  • 方法(A)在获取文章的所有标签时利用ndb的缓存机制,而在方法(B)的情况下需要查询(以及一些自定义缓存)

是否有一些我在这里缺少的东西,还有其他需要考虑的因素吗?

非常感谢您的帮助.

例子(A):

class Article(ndb.Model):
    title = ndb.StringProperty()
    # some more properties
    tags = ndb.KeyProperty(kind="Tag", repeated=True)

    def create_tag(self):
        # requires two writes
        tag = Tag(name="my_tag")
        tag.put()
        self.tags.append(tag)
        self.put()

    def get_tags(self):
        return ndb.get_multi(self.tags)

class Tag(ndb.Model):
    name = ndb.StringProperty()
    user = ndb.KeyProperty(Kind="User") #  User that created the tag
    # some more properties
Run Code Online (Sandbox Code Playgroud)

实施例(B):

class Article(ndb.Model):
    title = ndb.StringProperty()
    # some more properties

    def create_tag(self):
        # requires one write
        tag = Tag(name="my_tag", article=self.key)
        tag.put()

    def get_tags(self):
        # obviously we could cache this query in memcache
        return Tag.gql("WHERE article :1", self.key)

class Tag(ndb.Model):
    name = ndb.StringProperty()
    article = ndb.KeyProperty(kind="Article")
    user = ndb.KeyProperty(Kind="User") #  User that created the tag
    # some more properties
Run Code Online (Sandbox Code Playgroud)

kas*_*ere 6

您是否查看了有关使用Structured Properties https://developers.google.com/appengine/docs/python/ndb/properties#structured的以下内容.在简短的讨论有关于Contact并且Addresse可以简化您的问题.另请参阅https://developers.google.com/appengine/docs/python/ndb/queries#filtering_structured_properties.讨论非常简短.

此外,展望不允许连接这一事实,选项A看起来更好.