Discord.js等级系统:是否需在Mongo文档中存储Total XP?
要不要给Discord机器人的Mongo文档加Total XP字段?
我正在开发一款记录用户每条消息XP的Discord机器人,已经实现了升级所需XP的计算逻辑,现在纠结一个问题:要不要在Mongo文档里新增totalXp键值对?
当前的存储与升级逻辑
目前我的Mongo文档只存储xp字段,结构示例如下:
{ "name": "Ben", "discordId": "1234567890", "level": 1, "xp": 15 }
升级规则是:当用户的xp大于等于当前等级的升级所需值时,等级+1,同时将xp重置为0并保留溢出部分。
升级所需XP的计算公式为:
Math.floor(50 * (level ** 2))
1至5级的升级所需XP分别是:
- 50
- 200
- 450
- 800
- 1250
对应的各级别总XP门槛(即升到该等级所需的累计XP)是:
- 50
- 250(50+200)
- 700(50+200+450)
- 1500(50+200+450+800)
- 2750(50+200+450+800+1250)
未来我可能会用到用户的累计总XP(包括当前等级的已获得xp),现在纠结是直接在文档里加totalXp字段,还是用公式动态计算:
Math.floor(50 * (previous level ** 2) + xp)
两种方案的优缺点对比
方案一:新增totalXp字段
- 优势:
- 读取效率高:需要总XP时直接读取,无需计算,尤其适合排行榜、用户信息面板这类频繁展示的场景,能减少服务器计算开销
- 逻辑简单:避免了公式推导可能出现的错误,降低代码维护成本
- 兼容性强:如果未来调整升级公式(比如修改升级所需XP的计算方式),历史累计的
totalXp数据不会受影响,依然准确
- 劣势:
- 占用少量额外存储空间:但对于Mongo来说,单个文档多一个数字字段的开销几乎可以忽略
- 需要同步更新:每次给用户加XP时,既要更新
xp也要同步加totalXp,多一步操作,但逻辑简单不易出错
方案二:通过公式计算总XP
- 优势:
- 无需额外存储:节省一点点文档空间
- 少一个维护点:不用管
totalXp的更新逻辑,减少一处可能出错的环节
- 劣势:
- 计算开销大:每次需要总XP都要重新计算,当查询量较大(比如全服排行榜)时,会增加服务器负载
- 公式风险高:如果未来修改升级公式,用旧公式计算出的总XP会和实际累计值不符;而且当前给出的公式可能存在逻辑问题(比如用户当前等级1时,按公式计算总XP为15,但实际累计应该是升级到1级的50加上当前的15,即65,公式需要调整为所有前置等级所需XP的总和加当前xp)
- 调试成本高:如果总XP出现异常,需要排查公式逻辑,比直接读取字段更麻烦
个人建议
如果确定未来会频繁用到总XP(比如做排行榜、用户成长体系展示),优先选择新增totalXp字段。虽然多了一步更新操作,但从长期维护和性能角度来看,这种方案更稳妥,也能避免公式变动带来的历史数据偏差问题。
如果只是偶尔需要总XP,且能保证升级公式永远不会修改,那用公式计算也可以,但要先把公式的逻辑修正准确(比如计算所有前置等级所需XP的总和,再加上当前的xp)。
内容的提问来源于stack exchange,提问作者user874737
相关产品推荐
相关产品推荐

