www.boolean.name

www.boolean.name (http://forum.boolean.name/index.php)
-   Алгоритмика (http://forum.boolean.name/forumdisplay.php?f=21)
-   -   Работа с коллекциями в mongodb (http://forum.boolean.name/showthread.php?t=19536)

Lestar 24.11.2014 21:04

Работа с коллекциями в mongodb
 
Имеем юзера со свойствами:
Простые свойства:
- id
- token
- имя
- деньги
- опыт
- прочее
Сложные свойства(обьекты):
- постройки
- ресурсы
- шмот

В базе данных выполняются срезы до уровня какого либо простого свойства, какого либо здания или его свойства, какого либо ресурса или его свойства, вещи или ее свойства.

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

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

Lestar 25.11.2014 11:36

Ответ: Работа с коллекциями в mongodb
 
Немного почитал здесь http://rutracker.org/forum/viewtopic.php?t=4281804 . Автор вовсе рассказывает как удобно в одной коллекции иметь обьекты с различными свойствами. Чем то напомнило ситуацию с javascript, когда умельцы в один массив засовывают все что им под руку попадается, никак не реагируя на типизацию. Возможно я не совсем понимаю низкоуровневую логику mongodb и подобные действия, как и срезы по многоуровневой вложенности это норма.

moka 26.11.2014 16:10

Ответ: Работа с коллекциями в mongodb
 
Я придерживаюсь таких правил:
1. Если это one-to-one отношение, рассматривать как вложенный объект.
2. Если число суб-документов большое, рассматривать как отдельную коллекцию.
3. Если к индивидуальному суб-документу нужно часто обращаться, рассматривать как отдельную коллекцию.
4. Если число суб-документов фиксировано для относящегося документа, рассматривать key,value в документе.
5. Если суб-документы нужны всегда при запросе документа, то рассматривать как суб-документ.
6. Если суб-документ может "передаваться" в другие документы, то россматривать отдельную коллекцию.

Таким образом например, если у тебя ресурсы например: золото, металл, газ, то будет в юзере как:
Код:

{
    _id: ...,
    ...,
    resources: {
        gold: 64,
        metal: 0,
        gas: 128
    }
}

А вот постройки, к ним будут обращаться другие пользователи, и эти данные постоянно меняются, нужно обращаться индивидуально к постройке и т.п. Тут я бы сделал другую коллекцию.
Еще если у тебя например один большой мир, то если это отдельная коллекция с 2d индексом по координатам, то будет легко получить все постройки в радиусе/регионе, а если это будут суб-документы, то такого не получится.
Обращение к постройке по ID тоже проще в разы если это отдельная коллекция.

Шмот, тем более, т.к. если владелец шмота может меняться, то тут будет легче как отдельная коллекция, т.к. просто меняешь `owner` поле.
Также обращение к шмотке по ID в разы проще.

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

Я бы кинул постройки и шмот как отдельные коллекции, и ресурсы (если их менее 16) как вложенный объект (key,value) в юзере.

В плане token'а, я так понимаю это тип доступа к API по token'у? Тут лучше храни это дело как отдельная коллекция, и если у тебя разные клиенты (пользователи API) то пусть они имеют разные token'ы.
Это нормально сделать запрос на коллекцию где token на самом деле _id, и далее получить id пользователя.
Но если у тебя не будет несколько клиентов, или все твои клиенты - твои личные, тогда не парься с token'ами, имей сессию на стороне API с аутентификацией, и в сессии храни id пользователя, а сессию восстанавливай из пиченек (cookies), убедись что печеньки HTTPOnly и Secure.

Lestar 26.11.2014 16:29

Ответ: Работа с коллекциями в mongodb
 
У ресурсов сложная структура и типизация, с ними удобнее работать в отдельной коллекции. Токен это ключ доступа. Все трансформации обьектов только через токен, который генерится при коннекте пользователя. Получение данных возможно через id пользователя(есть ситуации, когда клиенту нужно в себя выгрузить чужие данные).

moka 26.11.2014 16:31

Ответ: Работа с коллекциями в mongodb
 
Если token генерится при коннекте пользователя, тогда у тебя будет проблема с несколькими клиентами одновременно.
По сути это сессия. Храни в сессии лучше, отдельно.

Если ресурсы тоже сложные, то храни отдельно.
Лучше не комбинировать сильно разные сущности в одну, если ты конкретно от этого не имеешь выгоду.

Lestar 26.11.2014 17:04

Ответ: Работа с коллекциями в mongodb
 
Не совсем понял какая может быть проблема. При коннекте пользователя ему возвращается 40-ка значный токен, он же ему прописывается в бд в профиль. Исключено валидное получение второго такого же ключа. Следующие любые обращения пользователя подписываются его токеном. При дисконнекте в базе чистим в его профиле токен. Да, по сути это аналог сессии. Это не веб , это мобильное приложение.

moka 26.11.2014 17:08

Ответ: Работа с коллекциями в mongodb
 
Если я залогинюсь одним и тем же пользователем с разных девайсов, у тебя одна сессия сделает токен, потом другая сделает токен, и пользователь с первой не сможет пользоваться приложением.

Такая проблема также будет если у тебя будет мобильный и веб клиент.

Lestar 26.11.2014 17:21

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

moka 26.11.2014 17:22

Ответ: Работа с коллекциями в mongodb
 
Ну тогда нормально.


Часовой пояс GMT +4, время: 23:14.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Перевод: zCarot