【问题标题】:Is this schema with nested subdocuments killing performance?这个带有嵌套子文档的模式是否会扼杀性能?
【发布时间】:2023-03-15 04:03:01
【问题描述】:

我正在构建一个基于浏览器的回合制 RPG,并构建了一个示例如下的数据模型。当玩家进行战斗时,读取和写入都将执行“灵魂”和“物品”子文档(数组),并进一步读取“技能”和“角色”子文档。我想每个数组都有 1-30 个子文档

为了提高性能,我尝试将几乎所有逻辑都包含在一个集合中,但是我在嵌套方面做得太过分了吗?

听说 MongoDB/MeteorJS 在使用嵌套数组时性能不佳,想了解一下这种数据模型是否可行?

    email: 'a@test'
    password: 'f321'
    profile:
      character: 
        _id: 'c001'
        location: 'Isenheim'
        name: 'Ugyr'
        race: 'human'
        level: 1
        experience: 1
        maxHealth: 10
        curHealth: 10
        curAp: 10
        maxAp: 10
        flagged: false
        gold: 0
        souls: [
          _id: 'S001'
          name: 'Hound'
          race: 'beast'
          cost: 5
          active: false
          maxHealth: 5
          curHealth: 5
          maxAp: 6
          curAp: 6
          skills: [
            name: 'Bite'
            damage: 1
            cost: 2
          ,
            name: 'Shred'
            damage: 2
            cost: 4
            effects: 
              name: 'Bleeding'
              duration: 2
              type: 'subtractive'
              stats: ['curHealth']
              value: 1
          ]
        ]
        skills: [
          name: 'Slash'
          type: 'direct'
          damage: 2
          cost: 2
        ,
          name: 'Pierce'
          type: 'direct'
          damage: 3
          cost: 3
        ,
          name: 'Throwing Knives'
          type: 'direct'
          damage: 1
          cost: 1
        ]
        items: 
          equiped: 
            weapon:
              name: 'Rusty Knife' 
              attack: 2
            shield: null

          inventory: [
            name: 'Potion'
            type: 'consumable'
            effects:
              type: 'additive'
              stats: ['curHealth', 'curAp']
              value: 3
            amount: 500
          ,
            name: 'Minor Soul Stone'
            type: 'consumable'
            amount: 500
            effects: [
              type: 'additive'
              stats: ['curAp']
              value: 2
            ,
              type: 'subtractive'
              stats: ['curHealth']
              value: 1
            ]
          ,
            name: 'Health Potion'
            type: 'consumable'
            amount: 100
            effects: [
              type: 'additive'
              stackable: false
              stats: ['curHealth']
              value: 1
              duration: 2
            ]
          ]
          conditions: [

          ]

【问题讨论】:

    标签: mongodb meteor


    【解决方案1】:

    是的,你在嵌套方面做得太过分了。

    Meteor DDP 仅发送第一级属性的更改/差异。因此,对soulsitems 的任何更改都将等同于再次发送整个profile

    我建议将charactersoulsitems 一起拆分为一个单独的集合。

    然后,将userId 非规范化到所有这些并一次性发布它们,例如:

    Meteor.publish("my-characters",function(){
      if (this.userId == null){
        return;
      }
      return [
        characters.find({"userId": this.userId}),
        characterSouls.find({"userId": this.userId}),
        characterItems.find({"userId": this.userId})
      ];
    });
    

    这可能会在发布游标和在线数据方面提供最佳性能。

    另外,不要忘记在userId 上建立索引:

    characters._ensureIndex({userId: 1});
    characterSouls._ensureIndex({userId: 1});
    characterItems._ensureIndex({userId: 1});
    

    【讨论】:

    • 感谢回复,我能正常化物品集合,因为它最多应该只有500个左右的文件,但每个角色可能有1-20个不同的灵魂,所以这意味着灵魂集合会非常大,在加入文档时可能会导致性能问题?
    • 什么时候需要加入?如果您添加 userId 字段(根据示例),那么您可以在不使用任何连接的情况下发布。如果您担心客户端性能,20 应该是最少的
    • 啊,我很困惑,我的错,但是你认为这个数据模型是否可以扩展以支持 1000 多个并发用户,大约 500 个请求/秒被发送到服务器?
    • 比您当前的模型要多得多;最终结果会因许多因素而异
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2015-10-11
    • 2018-10-19
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    相关资源
    最近更新 更多