代码之家  ›  专栏  ›  技术社区  ›  slacy

Django中数据非规范化的最佳方法?[闭门]

  •  14
  • slacy  · 技术社区  · 15 年前

    想象一下,有一个博客平台可以跟踪评论,而博客条目模型有一个“CommentCount”字段,我想让它保持最新。

    另一种方法是在我的代码中直接放置钩子,创建和销毁注释对象,以同步调用BlogEntry上的一些方法来增加/减少注释计数。

    我想还有其他的pythonic方法可以通过装饰师或其他巫毒来实现这一点。

    5 回复  |  直到 15 年前
        1
  •  17
  •   S.Lott    15 年前

    使用自定义管理器创建和维护FK关系。

    管理器可以在更新子项集时更新计数。

    save 方法您要对计数和总和进行非规范化处理的所有操作都可以在中完成 拯救

    你不需要信号。只是延伸 拯救 .

        2
  •  10
  •   gorsky    15 年前

    我发现 django-denorm 要有用。它使用数据库级触发器而不是信号,但据我所知,还有基于不同方法的分支。

        3
  •  5
  •   rob    15 年前


    然而,信号在某种程度上更难维护,因为依赖关系不那么明确(至少在我看来)。
    N 分钟

    非规范化将使维护更加困难 ; 出于这个原因,我会尝试 避开它 尽可能多地使用缓存或其他技术,例如使用 with comments.count as cnt
    然后,如果其他一切都失败了,并且只有在这种情况下,考虑什么可能是解决特定问题的最佳方法。

        4
  •  3
  •   Juande Carrion    10 年前

    Django提供了一个很好的、高效的(尽管不是很出名)替代方案 反规范化 .

    它将节省许多代码行,而且速度非常慢,因为您在同一个SQL查询中检索计数。

    class BlogEntry(models.Model):
         title = models.CharField()
         ...
    
    
    class Comment(models.Model):
         body = models.TextField()
         blog_entry = models.ForeignKey(BlogEntry)
    

    在your views.py中,使用 annotations :

    from django.db.models import Count
    
    def blog_entry_list(Request):
        blog_entries = BlogEntry.objects.annotate(count=Count('comment_set')).all()
        ...
    

    每个BlogEntry都有一个额外的字段,其中包含评论数,以及BlobEntry的其余字段。

    您也可以在模板中使用此额外字段:

    {% for blog_entry in blog_entries %}
      {{ blog_entry.title }} has {{ blog_entry.count }} comments!
    {% endfor %}
    

    这不仅可以节省编码和维护时间,而且非常有效(执行查询只需要稍长的时间)。

        5
  •  -1
  •   mipadi    15 年前

    为什么不使用 count() 方法:

    count = blog_entry.comment_set.count()
    

    或者,也可以在模板本身中执行以下操作:

    {{ blog_entry.comment_set.count }}
    

    获取评论的数量。