Хранение пользовательских данных в Google Cloud Datastore в качестве группы объектов - PullRequest
0 голосов
/ 13 июня 2018

Я пытаюсь найти лучший способ сохранить пользователя в хранилище данных Google (используя nodejs).У меня есть userId и объект userData:

userId: "some-random-string"

userData: {
    info: {
        name: "name",
        email: "test@email.com"
    },
    profile: {
        username: "user",
        status: "using"
    },
    stats: {
        stuffDone: 12,
        stuffNotDone: 20
    },
    inventory: {
        money: 100,
        items: ["first", "second", "third"]
    }
}

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

Таким образом, у меня будет корневая сущность (которая, вероятно, не будет существовать):

datastore.key(["Users", userId])

, тогда я создам 4 детейсохранить userData:

datastore.key(["Users", userId, "UserData", "Info"); --> userData.info
datastore.key(["Users", userId, "UserData", "Profile"); --> userData.profile
datastore.key(["Users", userId, "UserData", "Stats"); --> userData.stats
datastore.key(["Users", userId, "UserData", "Inventory"); --> userData.inventory

Только пользователь будет обновлять данные, поэтому конфликт не должен быть проблемой.Как только пользователь создан, мне не нужно обновлять более одного ребенка за раз.

Итак, скажем, статистика обновляется каждую минуту, я могу просто обновить ее напрямую с помощью ключа:

datastore.key(["Users", userId, "UserData", "Stats");

Не лучше ли разделить его на части вместо перезаписи всего пользовательского объекта в одну сущность и переписать все индексы?


С группой сущностей я все еще могу запроситьвсе пользовательские данные одновременно с:

query = datastore.createQuery().hasAncestor(datastore.key(["Users", userId]));

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


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

datastore.key(["UsersInfo", userId); --> userData.info
datastore.key(["UsersProfile", userId); --> userData.profile
datastore.key(["UsersStats", userId); --> userData.stats
datastore.key(["UsersInventory", userId); --> userData.inventory

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


Будут ли необходимы эти группы объектов или несколько объектов, если я обновляю только userData.statsи userData.profile примерно раз в минуту, или я должен просто использовать одну сущность.Объекты статистики и профиля будут больше, чем пара свойств.

1 Ответ

0 голосов
/ 13 июня 2018

Разделение объекта на несколько связанных объектов на основе шаблонов обновления свойств может быть хорошей идеей, особенно для крупных объектов, - чтобы избежать ненужной перезаписи всего объекта, когда изменяется только его часть (с соответствующим увеличениемпродолжительность обновления самой сущности и всех связанных с ней индексов. См. связанные повторное использование идентификатора сущности для других сущностей различных типов - вменяемая идея?

Размещение всей сущности "куски "в одну и ту же группу сущностей - которая, как вы заметили, позволяет вам делать запросы предков для извлечения пользовательских данных, это нормально, если вы соблюдаете макс. 1 запись / секунду для всей группы сущностей. Просто дважды проверьте, если выможно с уверенностью предположить, что результаты запроса поступают в определенном порядке, в противном случае вам может потребоваться предпринять шаги для обеспечения того, чтобы каждый результат направлялся к нужному объекту.

Использование отдельных «кусочков» сущности, не связанной с предком, позволяет повыситьобщая скорость записи, чем разделение с предком: максимум 1 запись / секна каждого субъекта.И технически вам не нужно делать 4 запросов для извлечения сущностей, но 4 ключевых поиска операций, см. Извлечение сущности .

Но разделение объекта может также увеличить ваши затраты на хранилище данных: одна операция чтения / записи для одного объекта будет умножена на количество «кусочков», на которые объект был разделен - в вашем случае 4, если вы читаете / записываете всеони вместе.

Таким образом, вам придется сбалансировать эти плюсы и минусы в контексте вашей заявки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...