在Django中对数据进行非规范化的最佳方法?

sla*_*acy 15 python mysql django

我正在开发一个简单的Web应用程序,存储一些非规范化数据很有意义.

想象一下跟踪评论的博客平台,BlogEntry模型有一个"CommentCount"字段,我想跟上它的最新状态.

这样做的一种方法是使用Django信号.

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

我想还有其他pythonic方法可以用装饰器或其他伏都教来实现这一点.

在Django中进行非规范化的标准设计模式是什么?在实践中,您是否还必须在出现错误时编写一致性检查程序和数据修复程序?

S.L*_*ott 18

您在Django有经理.

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

经理可以在更新子集时更新计数.

如果您不想制作自定义管理器,只需扩展该save方法即可.你想要做的非规范计数和总和的一切都可以完成save.

你不需要信号.只是延伸save.

  • 你知道这种风格的好例子吗?我很惊讶Django文档(或Django Book)根本没有提到非规范化方法...... (4认同)

gor*_*sky 11

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


rob*_*rob 5

第一种方法(信号)具有消除模型之间耦合的优点.
然而,信号在某种程度上更难以维护,因为依赖性不太明确(至少在我看来).
如果评论计数的正确性不那么重要,您还可以考虑一个每n分钟更新一次的cron作业.

但是,无论解决方案如何,非正规化都会使维护变得更加困难 ; 出于这个原因,我会尽可能地避免使用它,而是使用缓存或其他技术来解决 - 例如,with comments.count as cnt在模板中使用可能会提高性能.
然后,如果其他一切都失败了,并且只有在这种情况下,请考虑什么是特定问题的最佳方法.

  • 缓存将具有非规范化的所有维护问题,即保持缓存最新,在适当的时候使缓存的数据无效。更糟糕的是,您将无法享受 Django ORM 工具的好处。正如 @gorsky 所建议的,我的投票将投给 django-denorm - 如果您有它涵盖的非规范化用例之一,它会为您解决所有维护问题。 (2认同)