【问题标题】:Saving only modified fields仅保存修改的字段
【发布时间】:2015-08-21 09:47:32
【问题描述】:

我正在开发一款游戏,其中玩家根据他们在游戏世界中的位置在服务器之间切换,以在保持可扩展性的同时给人一种单一服务器的错觉。当玩家加入服务器时,他们的数据会从数据库 (MongoDB) 加载,当他们退出或更改服务器时,他们的数据会被保存。

我的问题来自于玩家数据从与玩家不同的服务器被修改的情况,这种情况需要偶尔发生。数据库中的数据已更改,但当玩家离开或更改服务器时,数据将被覆盖:

为了解决这个问题,我想只存储修改过的数据,因为通常您想要的数据是最近更改过的。然而,当我试图找到这样做的方法时,我注意到缺乏这样做的案例。是否有充分的理由不这样做并使用另一种方法来确保修改后的数据不被覆盖?我能想到的唯一问题是数据一致性,其中字段被更新并且只有其中一些被覆盖,这可能会使播放器处于无效状态,这可以通过同时更新所有相关字段来轻松避免。

如果有任何其他理由反对只保留一个对象的选择或任何其他方法来解决这个问题,但不会引入任何重大问题,我很想听听。

【问题讨论】:

  • 您可能需要考虑到,即使您已经充分解释了您的案例,但总体而言,这仍然是一个过于宽泛的问题。您真正要求的(并且可以搜索)是一般的“脏”概念。这意味着实际“更改”的数据是您要实际修改的“唯一”数据。在终端存储概念上,MongoDB 和其他引擎都有办法“仅”修改该数据。当然,一旦确定了要修改的内容。
  • 仅供评论。在“可爱”的一面。如果您向 MongoDB 提交了一个实际上与现有对象没有任何不同的“对象”,那么实际上不会将任何内容作为写入操作提交。但是您似乎在这里真正要问的是一种查看“哪些数据”实际上已更改的方法,然后仅将它们作为更改操作提交。如前所述,有点宽泛。
  • @user3561036 这个问题更多地是关于仅保留部分对象的可能问题以及这样做的替代方法,而不是实际实现。

标签: mongodb data-consistency


【解决方案1】:

这是数据库和代码之间底层状态变化的经典示例。

在您的玩家资料/数据文件中添加一个整数;称它为 v。假设 v = 6。

当玩家加入时,服务器会加载记录。服务器知道它的“本地”数据视图是 v = 6。当玩家离开时,代码将调用

findAndModify({query: {"userID":"ID1","v":6}, update: {"$inc": { v: 1}, "$set": { fldtochange: newval, anotherfldtochange: newval2  } } });

为简单起见,我们在此处显示文字 6,但它是在服务器加载期间填充的变量。仅当 v = 6 的原始值完好无损时,此命令才会成功。如果有人更改了它,则不会发生更新。您可以采取多种途径进行恢复,包括重新读取数据和对本地服务器中的状态进行增量。如果 v = 6 仍然存在,它会自动递增 +1(例如到 7),其余字段设置为新值。

【讨论】:

  • 有点迟到的评论,但有时在更新对象时,我正在使用带有 upsert 的更新。如果查询包含与任何内容都不匹配的版本号,则创建文档。有没有一种方法可以在不创建其他文档的情况下使用带有 upsert 的更新?
猜你喜欢
  • 1970-01-01
  • 2020-07-23
  • 2019-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 2022-01-17
  • 2019-03-12
相关资源
最近更新 更多