Django模型:通过相关模型跟踪活动?

时间:2012-06-11 14:56:25

标签: python django performance algorithm model

我有一些人员主表。我的Django应用程序中的所有内容都与一个或多个人有关,无论是直接还是通过长fk链。此外,我的所有模型都有标准的簿记字段'created_at'和'updated_at'。我想在Person表上添加一个名为'last_active_at'的字段,主要用于原始sql排序。

创建或编辑某些相关模型会为这些对象生成新的时间戳。我需要以某种方式用这些值更新Person.'last_active_at'。从功能上讲,这并不难实现,但我担心应用程序会受到过度压力。

我最关心的两个原因是我被限制在一个真正的数据库字段 - 我不能将一个函数作为@属性分配给Person表 - 其中一个'活动'模型接收和处理来自外部数据源的新实例我无法控制,偶尔会同时接收大量数据。

我的第一个想法是在'活动'模型中添加一个post_save挂钩。似乎仍然是我最好的选择,但我对他们一无所知,他们对数据库有多难,等等。

我的第二个想法是写一些经历当天活动的脚本,并在一夜之间更新这些模型。不过,我的雇主是一条“直播”。

我的第三个想法是修改post_save算法以检查'updated_at'是否距离Person的'last_active_at'不到半小时,如果为真,则不更新该人。

我的想法是否可以向可扩展的方向发展?我还有其他方法吗?

1 个答案:

答案 0 :(得分:2)

据说过早优化是所有问题的母亲。你应该从最愚蠢的实现开始(每次都更新它),然后测量并 - 如果需要 - 用更有效的东西替换它。

首先,我们提供一种方法来更新last_active_at上的Person字段。这样,所有更新逻辑本身都集中在这里,我们可以在以后轻松修改它。

信号非常易于使用:它只是声明一个函数并将其注册为接收器,并且每次发出信号时都会运行它。有关完整说明,请参阅the documentation,但这可能是这样的:

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=RelatedModel)
def my_handler(sender, **kwargs):
    # sender is the object being saved
    person = # Person to be updated
    person.update_activity()

至于更新本身,从最愚蠢的方式开始。

def update_activity(self):
    self.last_active_at = now()

然后测量并确定它是否是一个问题。如果这是一个问题,你可以做的一些事情是:

  • 在再次更新之前,检查先前的更新是否是最近的。如果对数据库的读取速度不比写入速度快,则可能无用。如果您使用缓存,则不会出现问题。
  • 在某个地方写下来,以便稍后更新延迟进程。无需每天:如果问题是每秒有100次更新,您可以让脚本每10秒或每分钟更新一次数据库。您可以使用这种技术找到一个良好的性能/ uptodatiness权衡。

这些只是基于你提出的建议,但正确的选择取决于你拥有的数字类型。确定你将拥有什么样的负载,该领域需要什么样的反应时间,然后进行实验。