2010-04-08 49 views
1

我想设计一个标记系统,这样的模式:设计一个标签表,告诉它使用多少次

Tag: 
    content = CharField 
    creator = ForeignKey 
    used = IntergerField 

它是标签之间的许多一对多的关系,什么是被标记。

每当我向分配表中插入一条记录时, 标记已用将加1,如果删除,则减1。

Tag.used被维护,因为我想加快回答'使用这个标签多少次?'的问题。

但是,这似乎显然减慢插入。

请告诉我如何改进这种设计。

在此先感谢。

http://www.pui.ch/phred/archives/2005/06/tagsystems-performance-tests.html

回答

1

如果你的数据库支持materialized indexed views,那么你可能要创建一个用于此。对于聚合数据的频繁运行查询,您可以获得很大的性能提升,我认为您在这里有。

您的看法是对的查询,如:

SELECT 
    TagID,COUNT(*) 
    FROM YourTable 
    GROUP BY TagID 

的聚集可以预先计算和存储在索引中,以尽量减少查询执行过程中昂贵的计算。

1

我不认为这是进行非规范化的数据一样,是个好主意。

我觉得更优雅的解决方案是通过调用像这样使用Django聚集跟踪有多少次标签已被用于http://docs.djangoproject.com/en/dev/topics/db/aggregation/

您可以在使用计数连接到您的标记对象:

my_tag = Tag.objects.annotate(used=Count('post'))[0] 

,然后访问它像这样:

my_tag.used 

假设你有一个具有多对多呸一个Post模型类LD您Tag类

如果需要,您可以为了通过名为注释字段标签:

Tag.objects.annotate(used=Count('post')).order_by('-used') 
+1

我认为这是很慢,如果我需要排序标记多少次,因为有一个“选择计数”查询每个标记。或者我的理解有什么问题? – satoru 2010-04-08 06:04:54

+0

您是否认为这会很慢,或者您实际上看到的是糟糕的表现?根据我的经验,Django ORM优化我的查询要比我手写的要好得多(我不是DBA)。 Aggregation返回一个查询集合,所以按照使用计数排序标签就像下面这样简单:Tag.objects.annotate(used = Count('post'))。order_by(' - used')。由于懒惰的查询,这将通过SQL调用来构建,排序,过滤和排序查询,这对于中小型站点来说应该足够快。 – digitaldreamer 2010-04-08 06:23:31

+0

谢谢,digitaldreamer。是的,我*只是*认为这会很慢,并试图设计一种'时间贸易空间',但我没有证据表明这样做更好,这就是为什么我在这里:) – satoru 2010-04-08 06:35:31

相关问题