简体   繁体   English

流水数据库的层次结构设计

[英]Meteor database design for hierarchical structure

I'm new to Meteor and Mongo, and I have some basic database design questions. 我是Meteor和Mongo的新手,并且有一些基本的数据库设计问题。

Let's say I'm making a turn based strategy game like Advance Wars . 假设我正在制作回合制策略游戏,例如Advance Wars I'm not sure how to structure my data. 我不确定如何构造数据。

I made a little demo where I did this in my html: 我做了一个小演示,在我的html中进行了此操作:

{{#each chars}}
  <div class='char' style={{get_style}}>
      ...
  </div>
{{/each}}

And I have this helper defined on Template.body: 我在Template.body上定义了这个帮助器:

Template.body.helpers({
  chars: function() {
    return Characters.find({});
  },
  ...
})

This works fine when I only have one game running at a time. 当我一次只运行一个游戏时,这很好用。 But I'm not sure how to make this work when I have multiple games running concurrently. 但是当我同时运行多个游戏时,我不确定如何使它正常工作。

I guess one way to do it would be to have a Games collection. 我想做到这一点的一种方法是拥有一个Games系列。 Each of these Games references two or more Players and each Player could have a list of Characters. 这些游戏中的每一个都引用两个或多个玩家,并且每个玩家都可以具有角色列表。 Each Character could have an x and y position. 每个字符可以具有x和y位置。 But then I'm not sure what query I would replace Characters.find({}) with. 但是然后我不确定用什么查询替换Characters.find({})

I guess it could be something like Game.findOne({game_id: game_id}).players[player_id].characters . 我猜可能是Game.findOne({game_id: game_id}).players[player_id].characters But I'm not sure what the performance implications are there. 但是我不确定性能会带来什么影响。 Would Meteor pull down the entire game object every time a character moves? 每当角色移动时,Meteor会拉下整个游戏对象吗? I don't really understand what Meteor is doing under the hood. 我不太了解Meteor在幕后所做的事情。

I guess another possibility that would require minimal changes would be to do something like Characters.find({game_id: 123, player_id: 1}) . 我猜可能需要进行最小限度更改的另一种可能性是执行Characters.find({game_id: 123, player_id: 1}) And then I would have all the Characters from all the games in one big collection. 然后,我会将所有游戏中的所有角色集中在一个大集合中。 It seems a bit strange to me to not have the Characters "encapsulated" under a Game, but maybe this is the way to go. 在游戏中没有“封装”角色对我来说有点奇怪,但这也许是可行的方法。

Actually, now that I've written that out, it seems like the second option makes more sense. 实际上,既然我已经写了出来,第二种选择似乎更有意义。 And I guess I would define all other internal game objects as separate collections. 而且我想我会将所有其他内部游戏对象定义为单独的集合。 Is this a good way to go about this? 这是解决这个问题的好方法吗?

Let's pretend your collection stores items that look like 让我们假装您的收藏商店看起来像

{
  _id: String,
  started: Date,
  players: [{
    _id: String,
    name: String,
    characters: [{
      _id: String,
      x: Number,
      y: Number
    }, {
      // ...
    }]
  }, {
    // ...
  }]
}

If you have an _id of a game and you need to get all the players and their characters, you do simply 如果您拥有游戏的_id ,并且需要获取所有玩家及其角色,则只需

let gameId = 'whatever';
const games = Games.find({
  _id: gameId
});

After that, in games , you have a cursor that will allow you to iterate over a single element, a game you selected by its ID (which is unique by design). 之后,在games ,您将拥有一个游标,该游标将允许您遍历单个元素,即通过其ID(在设计上是唯一的)选择的游戏。

Then, in your template, you do 然后,在您的模板中

<div class="games">
  {{#each games}}
    <h1>{{started}} — game's `started` scalar property.</h1>
    {{#each players}}
      <div class="player" id="{{_id}}">
        <h2 id="{{_id}}">{{name}} — player's name</h2>
        {{#each characters}}
          <h3 id="{{_id}}">{{x}}, {{y}} — coordinates of a character</h3>
        {{/each}}
      </div>
    {{/each}}
  {{/each}}
</div>

Note how _id respects current context. 注意_id如何尊重当前上下文。

Another way to do the same is use a plain-object instead of cursor, but your should use it only in cases you guarantee the query result to be a single element: 另一种方法是使用普通对象而不是游标,但是只有在保证查询结果为单个元素的情况下,才应使用它:

let gameId = 'whatever';
const game = Games.findOne({
  _id: gameId
});

The template will look a bit different. 模板看起来会有所不同。 Since you have a single plain-object, you don't have anything to iterate over. 由于您只有一个简单的对象,因此无需进行任何迭代。 So you can access properties of this object omitting the topmost context and replacing it with a with block: 因此,您可以访问该对象的属性,而忽略最上面的上下文,并用with块替换它:

<div class="game">
  {{#with game}}
    <h1>{{started}} — game's `started` scalar property.</h1>
    {{#each players}}
      <div class="player" id="{{_id}}">
        <h2 id="{{_id}}">{{name}} — player's name</h2>
        {{#each characters}}
          <h3 id="{{_id}}">{{x}}, {{y}} — coordinates of a character</h3>
        {{/each}}
      </div>
    {{/each}}
  {{/with}}
</div>

Please make sure that your template (or either the whole client) is subscribed to the Games collection, and this collection is published on the server and returns the whole field set and doesn't query the data (or it does but you control it). 请确保您的模板(或整个客户端)已订阅Games集合,并且此集合已发布在服务器上并返回整个字段集,并且不查询数据(或查询但可以控制数据) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM