2012-01-23 6 views
2

У меня есть проект движка приложения (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, поэтому не уверен, что их преимущества отрицаются. Может быть, это повредит больше, чем это поможет?

+2

может использовать фактический список для друзей; или даже лучше HashMap , чтобы вы могли получить среднее значение O (1) и улучшить операцию пересечения списка друзей. Учитывая, что у вас есть максимум 50 друзей, я сомневаюсь, что вы столкнетесь с проблемами производительности независимо от того, какой дизайн вы выберете. – Adrian

+0

Хороший вопрос, я обновил свой вопрос с помощью этой опции. Я думаю, что при чтении/сохранении в хранилище данных есть некоторые штрафы за сериализацию объектов List или Set. Я не уверен, могу ли я использовать запрос, чтобы полностью избежать этого при использовании списка. Было бы здорово. Спасибо – user291701

+0

, если вы должны пойти с длинным строчным подходом, вы можете ускорить поиск общих друзей, используя дерево префикса. Проблема становится подстрокой строки A в строке B. – Adrian

ответ

1

List<String> friends; - хорошее решение, которое я видел в профессиональном использовании. Если у друзей есть идентификаторы пользователя вашего приложения или google, вы можете использовать этот тип данных для списка ключей.

+0

Использование списков в аналогичном случае объясняется в презентации «Создание масштабируемых, сложных приложений на App Engine» из Google I/O 2009 http://www.youtube.com/ смотреть? v = AgaL6NGpkB8 – guigouz

1

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

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

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