【问题标题】:GAE organizing data structure problemGAE 组织数据结构问题
【发布时间】:2010-10-23 15:44:42
【问题描述】:

好的。我正在与 GAE 合作。我想创建这样的东西:

我有类型“组”“主题”“标签”:

  1. 每个“组”可以有多个 根据需要“主题”

  2. 每个“主题”可以有多个“标签” 根据需要

  3. 每个“组”可以有尽可能多的“标签” 根据需要

有点像圆圈。

现在我有这样的东西:

class TopicGroup(db.Model):
    value = db.StringProperty(required=True)

class Topic(db.Model):
    title = db.StringProperty(required=True)
    group = db.ReferenceProperty(TopicGroup, 'group', 'topics', required=True)

class TopicTag(db.Model):
    topic = db.ReferenceProperty(Topic, 'topic', 'tags', required=True)
    group = db.ReferenceProperty(TopicGroup, 'group', 'tags', required=True)
    value = db.StringProperty(required=True)

但这不好(在我的模型中“主题”只能有一个标签,但我需要“主题”有尽可能多的标签)

好吧,我的脑袋已经裂开了……有人可以帮忙吗?

【问题讨论】:

    标签: python database google-app-engine


    【解决方案1】:

    多对多连接可以实现为连接表(或关系模型)。在下面的解决方案中,有一个模型包含应用于单个 Groups (GroupTags) 的所有标签,还有一个模型包含应用于 Topics (TopicTags) 的标签。

    Tag 本身从对Tag 的引用中解耦,您可以执行更改标记的拼写等操作,而无需更新应用Tag 的每个GroupTopic

    此外,此模型还充分利用了 AppEngine 会在具有其他实体引用它们的实体上创建自动反向引用这一事实。在下面的模型中,Group 实体将有一个名为topics 的属性,该属性是一个查询,它将获取所有group 引用指向GroupTopic 实体。同样,每个Group 都从GroupsTags 模型中获得一个tags 属性,该属性为它提供了属于它的所有Tag 实体。每个Tag 实体都有一个groupstopics 属性,该属性是对分配了给定标签的那些类型的所有实体的查询,使得按标签搜索(一个非常典型的操作)非常简单。

    对于像您这样的系统建模来说,这是一种非常强大且灵活的方法。

    class Group(db.Model):
        # All of my group-specific data here.
    
    class Topic(db.Model):
        title = db.StringProperty(required=True)
        group = db.ReferenceProperty(Group, collection='topics')
        # other topic-specific data here.
    
    class Tag(db.Model):
        text = db.StringProperty(required=True)
    
    class GroupTags(db.Model):
        group = db.ReferenceProperty(Group, collection='tags')
        tag = db.ReferenceProperty(Tag, collection='groups')
    
    class TopicTags(db.Model):
        topic = db.ReferenceProperty(Topic, collection='tags')
        tag = db.ReferenceProperty(Tag, collection='topics')
    

    【讨论】:

    • 哇... Tnx 很多.. 你节省了我的一天 :) 我刚刚开始使用 GAE.. 所以这对我来说有点难。无论如何,再次tnx。
    【解决方案2】:

    解决方案是使用具有 db.Key 类型的 db.ListProperty。 见:http://code.google.com/appengine/articles/modeling.html(多对多部分)

    【讨论】:

    • 这种方法的主要限制是 ListProperty 被限制为 5000 个值。此外,执行诸如删除以这种方式引用的实体的所有引用等操作可能非常困难;您需要查询其列表中具有待删除键的每个实体,然后更新每个列表。这不能很好地扩展到大量实体。
    • 是的,但是 db.get(a_list) 更快。所以,这取决于你使用它。如果一个主题可以有超过 1mega 的键,好吧......但它不太可能
    • 您的观点是,在键列表上执行get 非常有效,因此如果系统不经常写入并且主要读取,那么您的解决方案具有有意义的优势。
    • Sahid 的解决方案对于诸如标签列表之类的情况要好得多。使用连接表进行删除并不比使用标签列表删除更便宜,而且只是稍微简单一点——而且它的扩展性也好不到哪里去。
    猜你喜欢
    • 2014-06-22
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    相关资源
    最近更新 更多