2012-06-11 63 views
1

我有一些人的主表。我的Django应用程序中的所有内容都与一个或多个人有关,无论是直接还是通过长时间连锁。另外,我所有的模型都有标准的簿记字段'created_at'和'updated_at'。我想在我的Person表上添加一个名为'last_active_at'的字段,主要用于原始的sql排序目的。Django模型:通过相关模型跟踪活动?

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

我最关心的两个问题是,我被限制在一个真正的db字段中 - 我无法将一个函数作为@属性分配给Person表,并且这些“活动”模型中的一个接收并处理来自外部数据源的新实例我无法控制,一次接收大量数据。

我的第一个想法是为'活动'模型添加post_save挂钩。仍然看起来像我最好的选择,但我对他们一无所知,他们多么难以击中分贝,等等。

我的第二个想法是写一些脚本,通过一天的活动,并在夜间更新这些模型。虽然我的雇主是'生活'流。

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

我的想法是否趋于可扩展的方向?我应该追求其他方法吗?

回答

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折衷。

这些只是一些虽然基于你的建议,但正确的选择取决于你有什么样的数字。确定你将拥有什么样的负载,该领域需要什么样的反应时间,以及实验。

+0

正在运行memcached ...需要appx半小时的响应时间...听起来像我需要推动prod并获得玩具的负载!谢谢。 –

+0

什么可能是一些好工具来衡量这种事情? –

+0

您可以轻松使用https://docs.djangoproject.com/en/1.2/faq/models/#faq-see-raw-sql-queries来测量查询所需的时间。对于更高级的配置文件,django-profiling看起来像一个不错的工具,但可能还有其他的。 – madjar