MongoDB: карта / юниты советуют для разработки модели в браузерной игре - PullRequest
2 голосов
/ 09 июля 2011

Я начал изучать MongoDB 2-3 дня назад, и я очень доволен этим :) Однако ... У меня есть некоторые вопросы ... Я уже провел некоторые исследования, и они не особо прояснили ... Я занимаюсь разработкой браузерной игры, и все базы данных были в MySQL, но я решил перейти на MongoDB. Но, ну, к вопросам.

1) В MySQL раньше у меня была таблица map , в которой были поля * map_ndx *, column , row, terrain (terrain был внешней ссылкой на таблицу terrain). По сути, каждый * map_ndx * указывает свою карту, а строка и столбец представляют их координаты; Ландшафт обозначает как «лес», «пустыня», отнесенные к другой таблице. Теперь на MongoDB у меня есть коллекция map , которая имеет поле * map_ndx * и встраивает несколько плиток . Каждая плитка имеет поля col и row и встраивает ландшафт . Прежде всего, вы думаете, этот дизайн эффективен для карты? Я сделаю много запросов, например, для поиска «tile (x, y) на карте z»). Во-вторых, где я могу разместить свои индексы (например, строка и столбец )? Поместить ли я их в коллекцию tile или в коллекцию map (например, с использованием индекса index.ile.row)? Я спрашиваю об этом, потому что на MySQL, когда я запрашивал «выбрать * из карт, где map_ndx = 1 и row = 1», у меня был бы ответ немедленно. В MongoDB, если я запрашиваю «Map.where (: map_ndx => 1) .first.tiles.where (: row => 1)», это займет почти секунду (обс .: синтаксис существует для RoR, Я работаю с mongoid )

2) В MySQL у меня раньше была таблица * global_units *, в которой было бы описание нескольких юнитов, их атак, защит, затрат и т. Д. И у каждого игрока было бы * user_units *, который ссылается на * global_units * и сообщает количество юнитов, которые игроки имели для этой ссылки * global_unit *. Теперь, на MongoDB , я рассмотрел встраивание * user_units * в коллекцию user , что кажется идеальным. Однако следует ли мне * user_units * только ссылаться на * global_units *, или было бы лучше, если бы * global_unit * был также встроен в коллекцию * user_units * каждого игрока? Проблема в том, что мне нужно было бы получить доступ к юнитам из * global_units * в других местах, например, когда игрок собирается их построить. Следовательно, даже если бы они были встроены в коллекцию * user_units *, мне также потребовалась бы эксклюзивная не встроенная коллекция * global_units *, чтобы я мог получить доступ к их информации в других местах. Какой самый лучший выход здесь?

Я знаю, что это очень конкретные вопросы, но я был бы рад, если бы кто-то разъяснил мне их! Заранее спасибо, Фернандо.

1 Ответ

3 голосов
/ 10 июля 2011

Вопрос, который вы задаете здесь, является сложным вопросом «вставлять или ссылаться».И первая проблема в том, что здесь нет единственно правильного ответа, это серия компромиссов.Иногда лучше ссылаться, иногда лучше встраивать.

Здесь есть ответ, который детализирует один пример .

Один из главных фундаментальных вопросов здесь вращается вокруг "topобъекты высокого уровня.Вот мое личное практическое правило:

  1. Если объект полезен только в контексте его родителя, то вы обычно встраиваете.
  2. Если объект полезен без его родителя, тогда вы обычно ссылаетесь.

Вопрос № 2 , я думаю, вы нашли здесь свои ответы:

  • user_units используется только в контексте user.Если вы собираетесь загрузить user, почему бы не загрузить одновременно units.
  • global_units полезен без контекста user_unit, поэтому вы, вероятно, захотите сослаться на него.Конечно, у вас есть «глобальный поиск» юнитов, но сколько у вас?Несколько сотен?Несколько тысяч?Они все вписываются в память?

Таким образом, user будет иметь что-то вроде

{ _id: 'gates',
  units: { footman: 10, cannon: 3, horse: 5 }
}

Это нормально, если пользователю нужен новый лакей, действительно ли этохлопот, чтобы посмотреть статистику?Конечно, если вы действительно хотите настроить, вы можете хранить статистику у моих лакеев, если они разные.

Вопрос № 1 : немного сложнее.

Как именно maps относится к tiles?Один map содержит много tiles?Вам удобно строить хеш-таблицу tiles в одном map?

Вот что я вижу:

{ _id: 'map1',
  name: 'jungle',
  height: 20,
  width: 20
  tiles: { "0_0": { type: 'jungle' },
           "0_1": { type: 'jungle' },
           ...
           "19_19": { type: 'beach' }
         }
}

Обратите внимание, что я не собираю массивплитки, но фактическая хеш-таблица.Я складываю все плитки в одну карту и загружаю все это в память.Конечно, это предполагает, что вы хотите, чтобы все плитки на карте были.

Я знаю, что ваш запрос рассматривает только одну строку, но теперь вопрос состоит в том, как часто вам нужна одна строка?Вам вообще не нужен квадратный блок плиток?

...