Я использую 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.
Я провел небольшое тестирование производительности, и, похоже, оно работает достаточно хорошо!