Наиболее эффективная схема базы данных для подсчета ключевых слов - PullRequest
1 голос
/ 08 июня 2011

Я работаю над приложением для iPhone с бэкэндом GAE. В настоящее время у меня есть база данных из ~ 8000 продуктов, и у каждого продукта есть 5 ключевых слов, извлеченных из обзоров, которые являются словами, которые наиболее часто используются для описания продукта. После развертывания приложения я бы хотел, чтобы пользователи могли добавлять новые продукты и добавлять свои 5 ключевых слов в существующие продукты. Таким образом, при «просмотре» существующего продукта они добавят свои 5 слов, и они будут отражены в 5 лучших словах, если они поместят слово в топ 5. Эти ключевые слова будут выбраны с помощью большого белого списка с косвенным выбором. так что я могу контролировать пользовательский ввод. Мне бы хотелось, чтобы приложение масштабировалось до тысяч пользователей, не слишком сильно ударяя по моему бэкэнду.

Мой вопрос: Какова наиболее эффективная схема базы данных для отслеживания всех слов для продукта и расчета 5 лучших для каждого продукта после его обновления?

Две мои идеи (которые могут быть ужасны):

  1. Иметь столбец "words", который содержит двумерный массив, одно измерение - это слово, а другое - количество для этого слова. Затем они будут увеличиваться / уменьшаться по мере необходимости.

  2. Иметь базу данных с каждым словом в виде столбца и каждым продуктом в виде строки, а соответствующая строка / столбец будет содержать счет.

Ответы [ 2 ]

2 голосов
/ 09 июня 2011

Самый простой способ сделать это - иметь вид тегов, определив что-то вроде этого (вы не указали внутренний язык, поэтому я предполагаю, что 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 тегов с наибольшим рейтингом для продукта.

0 голосов
/ 09 июня 2011

Вы должны использовать нормализованную схему, и пусть 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

Если вы действительно, действительно беспокоитесь о производительности, вы можете денормализовать результатыэтот запрос в таблицу, которая показывает слова для каждого приложения.Тогда вам нужно решить, как часто нужно обновлять этот снимок.

ПЕРЕСМОТРЕННЫЙ ОТВЕТ:

Как великодушно отметил Ник Джонсон, агрегатные функции недоступны в GQL.Однако философия моего ответа остается неизменной. Пусть ядро ​​базы данных выполнит свою работу.

Таблица должна быть AppID, Word и Frequency.(AppID и Word - это PK.) Затем каждое использование слова будет складываться по мере его применения.Затем, когда вы хотите узнать первые пять слов для приложения, которое вы выбираете по AppID: = @Value и упорядочьте по частоте (по убыванию) с LIMIT = 5.

Для отслеживания пользователя потребуется отдельная таблица.ключевые слова, если это важно.

...