【发布时间】:2018-11-22 10:02:56
【问题描述】:
我正在尝试找到将用户存储在谷歌数据存储中的最佳方式(使用 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,或者我应该只使用一个实体,是否需要这些实体组或多个实体。 stats 和 profile 对象将变得比几个属性更大。
【问题讨论】:
标签: node.js google-app-engine google-cloud-platform google-cloud-datastore