У меня есть проект движка приложения (java), который имеет класс User. Я бы хотел смоделировать дешевую систему отношений друзей. У каждого пользователя может быть максимум 50 друзей. Я имею в виду сделать что-то идиотский, как:Дешевый способ моделирования отношений друзей
class User {
String username;
Text friends; // "joe,mary,frank,pete"
}
Где «друзья» является разделенный запятыми список имен пользователей, которые пользователь дружит с. Вот операции, которые я хочу, чтобы поддержать и как бы я сделать их выше:
Принеси мой полный список друзей
Просто посмотреть объект пользователя, вернуться обратно, разделенных запятыми список друзей.
Добавить друга
Принеси мой пользовательский объект, проверьте, если целевое имя существует в строке, если нет, то добавьте в конец. Персистировать измененный объект пользователя обратно в хранилище данных.
Удалить другу
Принеси мой пользовательский объект, проверьте, если целевое имя существует в строке, если это произойдет, удалить его из строки. Персистировать измененный объект пользователя обратно в хранилище данных.
ли два пользователя взаимные друзья
Fetch как пользовательские объекты, убедитесь, что имена пользователей появляются на друг друга объекта пользователя.
Получение полного списка друзей очень важен для моего приложения и хранение каждого отношения, как отдельный объект кажется кошмарным мне (извлечение каждого объекта из хранилища данных, когда пользователь должен увидеть их список друзей будет, вероятно, обанкротил меня). Я надеюсь, что простое чтение атрибута Text будет намного более легким.
Проверка на общий сценарий друзей кажется самым большим недостатком здесь, но часто этого не произойдет. Я не знаю, будет ли извлечение двух объектов User из хранилища данных и выполнение сравнений строк будет катастрофическим по производительности. Может быть, хорошо? Я думаю, что, возможно, я также прочитал, что создание и удаление объектов из хранилища данных больше, чем просто изменение существующего объекта. Таким образом, операции добавления/удаления друга могут быть и лучше.
Был бы рад услышать любые мысли об этом или более оптимальных способах его решения.
Спасибо
-------------------------- Обновление ------------- --------
Как на комментарий Адриана, я мог бы также сделать следующее:
class User {
String username;
List<String> friends;
// or //
Set<String> friends;
}
Так что я думаю, что если я использую список, эти объекты будут индексироваться по умолчанию.Я не уверен, могу ли я выполнить GQL-запрос, зная, что списки индексируются, чтобы получить соответствие без фактического получения каких-либо объектов. Что-то вроде:
SELECT COUNT FROM User WHERE
(username = "me" && friends = "bob") &&
(username = "bob" && friends = "me")
Сохранение в качестве набора помогло бы сделать поиск быстрее, если я загрузил оба объекта пользователя, но я думаю, что и для списка и установка, дополнительное время должно быть принято десериализовать их, когда извлекается из datastore, поэтому не уверен, что их преимущества отрицаются. Может быть, это повредит больше, чем это поможет?
может использовать фактический список для друзей; или даже лучше HashMap , чтобы вы могли получить среднее значение O (1) и улучшить операцию пересечения списка друзей. Учитывая, что у вас есть максимум 50 друзей, я сомневаюсь, что вы столкнетесь с проблемами производительности независимо от того, какой дизайн вы выберете. –
Adrian
Хороший вопрос, я обновил свой вопрос с помощью этой опции. Я думаю, что при чтении/сохранении в хранилище данных есть некоторые штрафы за сериализацию объектов List или Set. Я не уверен, могу ли я использовать запрос, чтобы полностью избежать этого при использовании списка. Было бы здорово. Спасибо – user291701
, если вы должны пойти с длинным строчным подходом, вы можете ускорить поиск общих друзей, используя дерево префикса. Проблема становится подстрокой строки A в строке B. – Adrian