用于计算关键字的最有效数据库架构

时间:2011-06-08 18:43:25

标签: iphone ios google-app-engine database-design

我正在使用带有GAE后端的iPhone应用程序。我目前拥有一个包含约8000种产品的数据库,每种产品都有5个关键字,这些关键字来自评论,这些关键词最常用于描述产品。部署应用程序后,我想允许用户添加新产品,并将5个关键字添加到现有产品中。因此,在“审核”现有产品时,他们会添加他们的5个单词,如果他们将一个单词推到前5个单词,这些将反映在前5个单词中。这些关键字将通过间接选择的大白名单进行选择所以我可以控制用户输入。我希望这个应用程序可以扩展到成千上万的用户而不会过于强硬地使用我的后端。

我的问题是: 什么是最有效的数据库架构,用于跟踪产品的所有单词,并在每个产品更新后计算前5个?

我的两个想法(可能很糟糕):

  1. 有一个“单词”列,其中包含一个二维数组,一个维是单词,另一个是该单词的计数。然后根据需要递增/递减它们。

  2. 拥有一个数据库,每个单词作为一列,每个产品作为一行,相应的行/列将包含计数。

2 个答案:

答案 0 :(得分:2)

最简单的方法是使用'tags'类型,定义类似这样的东西(你没有指定后端语言,所以我假设是Python):

class Tag(db.Model):
  # Tags should be child entities of Products and have key name based on the tag
  # eg, created with Tag(parent=a_product, key_name='awesome', ...)
  count = db.IntegerProperty(required=True, default=0)

  @classmethod
  def increment_tags(cls, product, tag_names):
    def _tx():
      tags = cls.get_by_key_name(tag_names, parent=product)
      for i, tag in enumerate(tags):
        if tag is None:
          # New tag
          tags[i] = tag = cls(key_name=tag_names[i], parent=product)
        tag.count += 1
      db.put(tags)
    return db.run_in_transaction(_tx)

  @classmethod
  def get_top_product_tags(cls, product, num=5):
    return [x.key().name() for x
            in cls.all().ancestor(product).order('-count').fetch(num)]

increment_tags方法会增加所有相关标记的count属性。由于它们都具有相同的父实体,因此它们位于同一个实体组中,并且可以在一个事务中以事务方式执行此操作。

get_top_product_tags方法执行简单的数据存储区查询,以查找产品的num排名最高的代码。

答案 1 :(得分:-1)

您应该使用规范化架构,让SQL和数据库引擎成为您的朋友。有一个像这样的设计的表:

create table KeywordUse
( AppID     int
, UserID    int
, Sequence  int
, Word      varchar(50) -- or whatever makes sense
)

如果您愿意,也可以拥有身份主键,但AppID + UserID + Sequence是候选键(即这三者的组合必须是唯一的)。

要查找任何应用的前5个关键字,请执行以下SQL查询:

select top 5
  count(AppID) as Frequency -- If you have an identity PK count that instead.
, Word
from KeywordUse
where AppID = @AppIDVariable...
group by Word, AppID
order by count(AppID) desc

如果您真的非常担心性能,可以将此查询的结果反规范化为显示每个应用的单词的表格。然后你必须弄清楚刷新快照的频率。

已经修改过的答案:

正如Nick Johnson如此慷慨地指出的那样,GQL中没有聚合函数。但是,我的答案的理念仍然没有改变。 让数据库引擎完成它的工作。

该表应为AppID,Word和Frequency。 (AppID和Word是PK。)然后在应用时将每个词的使用加起来。然后,当您想知道AppID选择的应用程序的前五个单词时:= @Value并按频率排序(降序),LIMIT = 5.

如果这很重要,您需要一个单独的表来跟踪用户关键字。