Эффективные методы для хранения 2D массива / таблицы данных в базе данных SQL для быстрого доступа из php - PullRequest
4 голосов
/ 20 марта 2012

Небольшая команда программистов и я работаем над MMO-браузерной игрой с большой квадратной картой мира, где каждый индекс (x, y) ссылается на плитку на карте. Каждый тайл имеет пару значений для хранения идентификатора типа местности и случайно сгенерированного начального числа, которое будет использоваться для процедурной генерации. Эта карта будет в диапазоне от 1500x1500 до 500x500 квадратных плиток.

Нам нужен эффективный способ хранения этой таблицы на сервере, предпочтительно в базе данных SQL, чтобы можно было получить доступ к меньшим квадратным фрагментам карты и отправить их игроку для отображения их браузером.

При доступе к данным карты всегда будут соблюдаться следующие условия.

  • Данные карты никогда не будут обновляться после их сохранения в базе данных
  • Полная карта никогда не будет доступна сразу
  • В любом заданном запросе будут доступны только небольшие прямоугольные части карты в диапазоне от одной плитки до максимум 50x50 квадрата в таблице

Учитывая эти условия, какими будут наши варианты хранения данных в базе данных MySQL, чтобы доступ к прямоугольным частям данных был быстрым и, предпочтительно, с одинаковой скоростью независимо от положения данных в таблице?

Один из членов нашей команды придумал этот метод макета для таблицы SQL, где каждая строка является плиткой на карте:

|------------------------------------------------------------| 
|                        table:  map                         | 
|------------------------------------------------------------| 
|      coord       |      tile      | attrs |      seed      | 
|------------------|----------------|-------|----------------| 
|mediumint unsigned|tinyint unsigned| text  |tinyint unsigned| 
|   unique index   |                |       |                | 
|------------------|----------------|-------|----------------| 
  • ordin : Комбинация координат X и Y плитки на карте мира. Рассчитывается через X + (Y<<11) для карты 1500х1500. (Обратите внимание, что для тестовой карты 50x50 используйте X + (Y<<6))
  • плитка : числовой идентификатор типа местности плитки
  • attrs : любые атрибуты, которые нам нужно сохранить для изменения плитки,
  • seed : случайно сгенерированное семя для плитки

Никто из членов нашей команды не имеет опыта проектирования таблиц SQL, поэтому мы не можем знать, является ли это хорошим методом, или каковы узкие места или замедления

Мы ищем ответ, в котором представлены наши варианты дизайна нашей таблицы или таблиц, а также преимущества и недостатки выбора каждого варианта. Также, если вы действительно хороши, пример запроса на вытягивание прямоугольного фрагмента карты из базы данных (например, от (0, 0) до (5, 5)) был бы хорош.

РЕДАКТИРОВАТЬ , если есть опция, отличная от MySQL, которая будет быстрее, например, сохранить ее в локальном файле на сервере, который также является правильным ответом, однако я хотел бы получить какое-то объяснение относительно почему это будет быстрее в этих условиях

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

1 Ответ

1 голос
/ 20 марта 2012

Лично я бы изложил это следующим образом.

Плитки карт

id - primary key
mapId - indexed
xCoord - indexed
yCoord - indexed
tileId

Карты

id - primary key
tileSetId

События

id -  primary key
mapId - indexed
xCoord - indexed
yCoord - indexed
proceeduralInstructions

Важными являются показатели скорости поиска.Я добавил mapId в таблицу Map Tiles, чтобы вы могли хранить более одной карты в этой таблице.Таблица «Карта» будет содержать информацию, специфичную для карты, например, набор плиток (изображение), из которого вы используете карту.События могут быть добавлены на карту при рендеринге.Вы можете придумать краткую процедурную инструкцию для размещения непосредственно в БД, которая может быть интерпретирована движком.Возможно, вы бы также добавили еще одну таблицу для спрайтов и, возможно, еще один столбец в таблицу плиток карты, для которой должен быть нарисован слой плитки (некоторые вещи будут появляться перед вашими персонажами, а другие позади).Возможно, вам даже понадобятся два слоя переднего плана и два слоя фона, чтобы вы могли накладывать друг на друга изображения с частичной прозрачностью для более богатых карт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...