Objectify/GAE — конкретная проблема денормализации

Я использую Google App Engine и Objectify 3.1 и медленно изучаю денормализацию и проектирование сущностей на основе их использования, но я все еще борюсь с некоторыми аспектами.

В настоящее время я создаю систему, в которой объект «Пользователь» может участвовать в объекте «Игра» и должен иметь возможность находить все игры, в которых участвует пользователь. Как я это вижу, есть два основных решения:

Решение 1)

Сохраните список пользовательских ключей (participantKeys) в игре и найдите игры, в которых участвует участник, следующим образом:

List<Key<User>> userList = new ArrayList<Key<User>>();
userList.add(new Key<User>(User.class, myUserId));
Collection<Game> games = ofy().query(Game.class).filter("participantKeys in" , userList).list();

Решение 2)

Помимо хранения списка участников в игровом объекте, также сохраните список игр, в которых пользователь участвовал в пользовательском объекте, и найдите такие игры:

User myUser = userDao.getUser(myUserId);
Collection<Game> games = user.getParticipatedGameKeys();

Решение 1 станет довольно медленным, если в системе много игр.

Решение 2 ускорит поиск игр, но мне нужно будет постоянно обновлять список, когда пользователи присоединяются к играм и покидают их.

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

Мне не хватает более элегантного решения? Ни один из вышеперечисленных не кажется очень привлекательным.

Любая помощь приветствуется!

Изменить:

Я решил попробовать что-то вроде того, что предложил Микл, после долгого размышления об альтернативах ... так что приятно слышать решение, которое очень похоже на это :-)

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

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

Я провел небольшое тестирование производительности, и, похоже, оно работает достаточно хорошо!


person Javasmurf    schedule 26.06.2012    source источник


Ответы (1)


у вас также может быть другой объект, я не знаю, как вы можете его назвать (UserGame?), но в этом объекте вы будете хранить ключ игры, ключ пользователя, а также некоторую информацию, к которой вы хотите получить доступ, например, пользователь имя, название игры и так далее. Затем, когда пользователь войдет в игру, вы создадите эту сущность.

С помощью этого объекта вы можете легко получить игры, в которых участвует участник, а также всех пользователей, которые участвуют в игре.

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

Я не знаю, хорошее ли это решение, но оно должно работать.

person Mikl    schedule 28.06.2012