Более эффективный SQL-запрос - PullRequest
0 голосов
/ 15 декабря 2011

Я создаю многопользовательскую игру «Найди отличия».

Характеристики игры:

  1. В каждой игре может быть до 10 игроков.
  2. Пользователь не должен видеть одно и то же изображение дважды.
    (изображение состоит из четыре изображения, и пользователь должен «заметить разницу» между ними) .

У меня есть коллекция тысяч и, возможно, даже десятков тысяч из картинки на выбор. Проблема, с которой я сталкиваюсь, чрезвычайно неэффективный и не масштабируемый метод поиска изображения, которое ни один из Игроков еще не видели.

В моей базе данных есть usage table со следующими полями:

  1. picture_id
  2. user_id

Мое текущее решение выглядит следующим образом:

Пользователь входит в игру, приложение выбирает изображение из базы данных, которое не отображается в таблице использования для этого пользователя, и для каждого входящего пользователя я запускаю ту же функцию, только добавляя значения изображений, которые есть у других пользователей в той же игре уже видел.

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

Этот метод не очень масштабируемый, и я ожидаю довольно стабильного потока постоянного трафика, что означает, что во многих играх играют.


У кого-нибудь есть предложения по улучшению этой логики или предложения по улучшению структуры базы данных?

Ответы [ 3 ]

4 голосов
/ 15 декабря 2011

Вы можете просто добавить в таблицу изображений поле (не отображение пользователя / изображения), которое помечает, использовалось ли изображение.Затем вы можете установить этот флаг всякий раз, когда используются изображения, и индексировать это поле для быстрой идентификации неиспользуемых изображений.Это эффективно кеширует результат в функцию hasBeenUsed ().

Некоторые люди могут возражать по-разному, и такая преждевременная оптимизация может привести к сильно загроможденной и очень тесно связанной структуре.Наказание за ремонтопригодность в будущем.

Альтернативой является каждое изображение в таблице отображения пользователя / изображения.Если изображение не используется, связанный с ним user_id остается равным NULL.Индекс с параметром picture_id первым очень быстро идентифицирует неиспользуемые изображения.

Но, прежде всего, это зависит от того, какой запрос вы должны сделать для этого случайного выбора.Очень часто (но не всегда) плохо масштабируемые алгоритмы могут быть заменены гораздо более масштабируемыми алгоритмами без какого-либо изменения структуры базы данных.Но чтобы знать, что нам нужно увидеть ваш запрос, а также схему и поведенческую информацию о данных (ограничения, вероятный% неиспользованных и т. Д.).

3 голосов
/ 15 декабря 2011

Я думаю, что это преждевременная оптимизация.

В то время как «десятки тысяч» для человека звучат очень много, для движка SQL это почти ничего.Некоторые реализации даже не будут использовать индексы для таблицы длиной менее 50–60 тыс. Строк, потому что быстрее загружать все это в память.

Я бы рекомендовал писать запросы, используя EXISTS, что в большинстве случаев приводит к коротким замыканиям.реализации и должны быть достаточно быстрыми для ваших целей.

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

0 голосов
/ 15 декабря 2011

10 пользователей против 10000 изображений - используя теорию вероятности, вам нужно выбрать 11 изображений (я предлагаю использовать некоторый случайный подход) после проверки внутри этих 11, чтобы найти первый уникальный.

...