Задать вопрос

Каким образом хранить большой (2400*1800) двумерный массив в БД?

Есть несколько двумерных массивов размерностью 2400*1800 и выше, значения составляют числа 0-255. (Суть - это карта like Terraria, значение составляет тип элемента на карте). Считывание с этой базы должно происходить запросом из любой части массива подмассива 100*100 элементов.

Собственно, проблема состоит в том, что простейший способ хранить и использовать 4+ миллиона значений на каждый массив это несколько затратное с точки зрения производительности дело.

Данные динамические

Собственно, поэтому возникло несколько предположений по решению проблемы:
1. Втупую заводить на каждый массив табличку в MySQL (PostgreSQL), думая до последнего, что производительность не упадёт.
2. Разбить массив на подмассивы по 100*100 элементов, и эти уже массивы хранить как форматированный текст TBLOB в БД. Неизвестно, насколько такой метод используем.
3. Использовать Sqlite и иже с ним.
4. Использовать нетабличное хранение информации, например, в файле без использования каких-нибудь систематизированных способов разметки.
5. Использовать xml язык или нечто похожее.
6. Другой вариант.

Собственно, что лучше?
  • Вопрос задан
  • 5463 просмотра
Подписаться 9 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 6
@rPman
Ваша задача очень эффективно решается обычным файлом на диске (открытый с запретом lazy writes, либо принудительным flush после каждой записи). Если инструментарий (язык программирования и библиотеки) позволяет - откройте файл маппингом на память.
Индекс для таких запросов не нужен, ведь ячейки можно индексировать примитивно - (x+maxx*y). запрос 100x100 блока превращается в 100 быстрых чтений по 100байт. Если это оправдано, можно хранить не ячейки а блоки 100x100, тогда при чтении будет читаться в 4 раза больше данных но четырьмя чтениями. Но если блок данных экрана влезает в буфер опережающего чтения операционной системы (драйвере файловой системы) то такой метод хранения будет неактуален.

Любой другой метод будет медленный либо по записи (например хранить в базе не ячейки а блоки 100x100, соответственно при запросе блока будут считываться четыре соседних), либо медленный по чтению (хранить по одной записи на ячейку) и не эффективный по месту на диске.
Ответ написан
morozovdenis
@morozovdenis
мне кажется привлекательной идея с файлом

вот как мне это видится(упрощу до 5х5):

создаём файл размером 25 байт забитый нулями:
0000000000000000000000000

и пишем фукнцим считывания/записи массива пусть будет 2х2():
псевдо код
bool write(f, char[2][2] data, start_x, start_y, width)
{
         f_seek(f, start_y * width + start_x);
         f_write(f, data[0]);
         f_seek(f, (start_y + 1) * width + start_x);
         f_write(f, data[1]);
         return true;
}

char[2][2] read(f, start_x, start_y, width)
{
         char[2][2] result;
         f_seek(f, start_y * width + start_x);
         result[0] = f_read(f, 2); // читаем два элемента
         f_seek(f, (start_y + 1) * width + start_x);
         result[1] = f_read(f, 2); // читаем два элемента
}


тут нет защиты от сбоев

надр поискать NoSQL базы с возможностью хранить массивы
Ответ написан
Комментировать
begemot_sun
@begemot_sun
Программист в душе.
Имхо. Зависит от ваших задач. Я бы остановился на 100х100 .. и вообще зачем вам карту хранить в бд ? Какие выборки ?
Ответ написан
Комментировать
Если данные динамические или нужен поиск по ячейкам (всем), то делаем в базе именно такую таблицу 2400*1800. MySQL должен осилить без тормозов.

Если данные не динамические и поиск по ячейкам не нужен, то лучше использовать файл.
Ответ написан
Комментировать
svd71
@svd71
А почему не устраивает обычная таблица с тремя полями?
create table dimmension (
dimIdx1 int not null,
dimIdx2 int not null,
val char
);
Ответ написан
vipuhoff
@vipuhoff
храни карту в виде bitmap картинки, 255*255*255 цветов для хранения кода твоего объекта будет 100500 раз достаточно. Считывать соответственно можешь как обычную картинку. Получится "Массив" хоть 25000 на 25000 при определенном подходе будет работать быстрее чем такое в БД:)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы