1

好吧,假设我正在制作一场盲战游戏!用户 A 和 B 有 x 数量的士兵

当前有 0 个数据库文档。

用户 A 派 50 名士兵制作数据库文档 用户 B 在用户 A 之后派 62 名士兵!

这将创建一个新的数据库文档。

我需要最有效/可扩展的方式来查找用户 A 的文档,将其与用户 B 的文档进行比较,然后删除两个文档!(当然返回结果后)

这就是问题所在!我可能有 10,000 多个用户同时派兵!怎样才能顺利完成上述过程而不重叠呢?

我正在使用 MEANstack 进行开发,因此我不仅限于在数据库中执行此操作,而且显然 WebApp 必须 100% 安全!

如果您需要任何其他信息或解释,请告诉我,我会更新这个问题

-谢谢

4

1 回答 1

2

这里想到的一件事是您可能不需要做所有您认为需要做的工作,并且您的问题可能会在TTL 索引和可能有上限的集合的帮助下得到解决。考虑以下条目:

{ "_id" : ObjectId("531cf5f3ba53b9dd07756bb7"), "user" : "A", "units" : 50 }
{ "_id" : ObjectId("531cf622ba53b9dd07756bb9"), "user" : "B", "units" : 62 }

所以有两个条目,_id当你插入时你得到了那个值。所以一开始,“A”没有人可以对抗,但“B”的条目将与之前的人对抗。

ObejctId 是单调的,这意味着“下一个”总是比上一个值更大。因此,使用插入的数据,只需执行以下操作:

db.moves.find({ 
    _id: {$lt: ObjectId("531cf622ba53b9dd07756bb9") }, 
    user: { $ne: "B" } 
}).limit(1)

这将前面插入的“移动”赋予刚刚进行的当前移动,并且这样做是因为先前插入的任何东西都将具有_id比当前项目更小的值。您还要确保您没有“玩”用户自己的举动,当然您将结果限制在一个文档中。

所以“移动”将永远向前,当用户“C”进行下一次插入时,他们从用户“B”那里获得“移动”,然后用户“A”将从用户“C”那里获得“移动” “, 等等。

这里“可能”发生的所有事情都是“B”按顺序进行下一个“移动”,并且您将拾取与上一个请求中相同的文档。但这是你的“会话”设计的重点,存储最后的“结果”并确保你没有得到同样的东西,因此,在你的设计中处理想要的任何东西。

这应该足以“玩”。但是,让我们进入您的“删除”部分。

自然你“认为”你想删除东西,但回到我最初的“帮手”,这应该是没有必要的。从上面看,删除只是“清理”的一个因素,所以你的收藏不会增长到很大的比例。

如果你应用了一个 TTL 索引,就像本教程解释的那样,你的集合条目将被清理,并在一段时间后被删除。

还有什么可以做的,特别是考虑到我们正在使用密钥的增加性质_id并且这或多或少是一个“队列”本质上,你可以将它应用为一个上限集合。因此,您可以将最大尺寸设置为在任何给定时间将保留多少“移动” 。

将这两者结合在一起,你会得到一些只会“增长”到一定大小的东西,并且会自动为你清理,如果活动慢一点的话。这将使所有操作保持快速

底线是,您担心的“删除”并发性已通过实际“删除”删除刚刚播放的文档的需要而被删除。查询保持简单,TTL 索引和上限集合为您管理数据。

所以你有我对一个非常并发的“盲战”游戏的看法。

于 2014-03-10T02:08:40.330 回答