LINUX.ORG.RU

MySQL как лучше хранить матрицу


3

5

Доброго времени суток! Подскажите пожалуйста, как лучше хранить двумерный массив? Суть в том, что у меня в базе должны хранится карты высот. Каждая карта представляет собой двумерный массив размерностью 720*720.

Я почитал советы - некоторые предлагают для хранения массива использовать отдельную таблицу. Но у меня таких записей будет порядка 5000 штук. Как-то наверное много таблиц получится.

Конечно самый простой вариант хранить данные в тексте. Но парсинг текста требует много времени. Может кто еще что посоветует?

Заранее огромное спасибо!

Решить это можно только отталкиваясь от того какие и как ты будешь запрашивать данные, и как их обрабатывать.

thesame ★★★★ ()
Ответ на: комментарий от thesame

Спасибо большое за ответ! В базе хранится дата и матрица. Пользователь запрашивает карту за определенную дату. Т.е. за раз будет запрашиваться только один массив.

gwyllum ()
Ответ на: комментарий от gwyllum

Ну так SQlite это даже не MySQL... Тогда пили таблицу:

[id], [matrix_id], [X], [Y], [value]

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

Alve ★★★★★ ()
Ответ на: комментарий от Alve

Интересная идея, сейчас попробую реализовать. Спасибо огромное!

gwyllum ()
Ответ на: комментарий от gwyllum

Пользователь запрашивает карту за определенную дату. Т.е. за раз будет запрашиваться только один массив.

berkeleyDB?

AF ★★★ ()

Как вы любите придумывать всякую байду - я просто поражаюсь вашей сообразительности.

Берёшь сишку и дампишь свои 5000*720*720 в файлец, тебе даже индекс не нужен, потом читаешь за 1сискол. Это а) в мильён раз быстрее твоей любой бд, б) в тысячи раз проще/надёжней. в) не нужно пилить стопицот кастылей для такого ущербства, как db.

А теперь подумай, что является лучшим выбором: три строчки на сишке + сискол, либо хренпоймичто какая-то бд+стопицот тысяч строк.

superhackkiller1997 ()
Ответ на: комментарий от superhackkiller1997

5000*720*720 это около 2,4 Гб :) Я понимаю память дешевая, но слышать такие советы от человека, который предлагает быстрый, минимальный си как-то даже не смешно :)

gh0stwizard ★★★★★ ()
Ответ на: комментарий от gh0stwizard

Хм, а в бд они будут занимать ещё больше места. Если ты говоришь про оперативу - перечитай мою месагу и укажи где там говорится про оперативу.

Читаешь не весь файл, если ты об этом подумал, а по оффсету(man read(), lseek(), etc), который ты можешь вычислить без индекса. Читаешь ты ровно 720*720, что требует 720*720 оперативы( что является минимум, меньше которого без тормазов ты не получишь нигде).

superhackkiller1997 ()
Ответ на: комментарий от superhackkiller1997

Читаешь не весь файл, если ты об этом подумал, а по оффсету(man read(), lseek(), etc), который ты можешь вычислить без индекса.

Поясни человеку, зачем ему заново писать то, что давно реализовано в самых примитивных СУБД в сто раз лучше? Кроме того, надо заранее закладывать возможно безболезненно добавить фичи. Завтра он захочет найти среди своих карт высот какие-то определённые точки - что ж ему, на сишечке опять изобретать то, что даже sqlite умеет? ))

Alve ★★★★★ ()
Ответ на: комментарий от gwyllum

Непонятно каким боком тут скулайт. Положи все матрицы в разные файлы двоичным потоком в максимально естественном формате и не парься.

anonymous ()
Ответ на: комментарий от Alve

В сто раз лучше? Это тебе в школе рассказали?

Даже 10% перфоманса моих 3-х строк твоя самая лучшая субд не даст, поэтому с этим ты можешь только соседям по парте пристовать.

Да, напишет на сишке, ибо это займёт у него минут 5 времени и 1000% перфоманса скулайта, а на чтение мана скулайта он потратит полчаса, плюс запилить надо + разобрать выхлоп скулайта, что отнимит у него минимум час.

Поэтому, не рассказывай мне про свои анскильношаблоннные предрассудки из детсада, а говори что-то поделу.

superhackkiller1997 ()
Ответ на: комментарий от Alve

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

anonymous ()
Ответ на: комментарий от superhackkiller1997

А еще он потратит время на конверсии скулайт -> си-значение, так бережно сэкономленное на парсинге текста :)

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

anonymous ()
Ответ на: комментарий от anonymous

Угу, я на это указал вот тут: «разобрать выхлоп скулайта».

Ну это ООП головного мозга и вера в скулайт.

superhackkiller1997 ()
Ответ на: комментарий от superhackkiller1997

Поддерживаю. Тут еще можно будет кеширование в памяти или mmap использовать для полной оптимизации.

nerdogeek ()

Ты толком не описал структуру данных для одной записи. Думаю там координаты вообще хранить не надо. Х=i / row_size, Y=i % row_size. Где i - порядковый номер записи.

nerdogeek ()
Ответ на: комментарий от superhackkiller1997

Читаешь не весь файл

Вроде как человеку нужен одновременный доступ к 5000 координат (или неодновременный; ТС кстати не пояснил эту деталь). Так что пусть думает сам :) Но твое решение тоже неидеально, хотя и имеет массу приемуществ.

Тем не менее, мапить файл рано или поздно придется, когда внезапно понадобиться 50 000 или 100 000 координат. А мапинг уже не один сискол :)

gh0stwizard ★★★★★ ()
Ответ на: комментарий от gh0stwizard

Вроде как человеку нужен одновременный доступ к 5000 координат (или неодновременный; ТС кстати не пояснил эту деталь). Так что пусть думает сам :) Но твое решение тоже неидеально, хотя и имеет массу приемуществ.

Без разницы какой, хоть 100500ременный. Оно идеально, ибо лучше не запилить.

Тем не менее, мапить файл рано или поздно придется, когда внезапно понадобиться 50 000 или 100 000 координат. А мапинг уже не один сискол :)

Не имеет смысла, хоть там мильярд координат, да и на этом загнётся бд.

superhackkiller1997 ()
Ответ на: комментарий от superhackkiller1997

Ну тут либо шашечки, либо ехать, хоть как-то. А вообщея с твоей мыслью согласен. Модель данных у ТСа не реляционная, забивать гвозди микроскопом причин не вижу.

Dantix ★★ ()
Ответ на: комментарий от gh0stwizard

И что?

/dev/mapper/data-share1    4.1T         3.4T  759G           82% /home/share1

От блин нахрен, у меня есть десяток теребай, а у него нет - ну да.

Ещё раз, если ты не осилил read() и lseek() - это твои проблемы. Читает он 720 * 720, хоть 100500гигов у тебя будь.

В любом случае у тебя будет занимать это 5000 * 720 * 720, что ты мне этим хочешь сказать?

superhackkiller1997 ()
Ответ на: комментарий от true_admin

Засунь каждую карту в отдельный файл. Так будет со всех сторон проще.

По реализации в коде может и проще, но тогда автор получит 5000 файлов. Нафига это нужно? Лучше уж либо read + seek заюзать, либо BLOB в SQLite, чтобы все данные в один файл слить.

Norgat ★★★★★ ()
Последнее исправление: Norgat (всего исправлений: 1)

Ключевое слово BLOB. BLOB это потоковое значение, фактически файл.

CREATE TABLE MyTable(
name VARCHAR(10),
map BLOB
);
под sqlite оно доступно через sqlite3_bind_blob и sqlite3_column_blob .

vtVitus ★★★★★ ()
Последнее исправление: vtVitus (всего исправлений: 1)
Ответ на: комментарий от gh0stwizard

1. По себе людей не судят.

ок.

2. Я говорил про ОЗУ, а не место на МЖД.

А причем тут ОЗУ? Как в моём описании в ОЗУ появится 2.4гига - это лишь в твоих мечтах

superhackkiller1997 ()
Ответ на: комментарий от gh0stwizard

НЖМД если так уж охота выпендриться.

Ты правда не понимаешь, что файл можно читать не с начала и до обеда, а с любого места по любое? Или ты решил рассмотреть гипотетическую ситуацию загрузки вообще всех матриц в память одновременно, и уверен, что БД тебя в этом случае магически спасет?

anonymous ()
Ответ на: комментарий от gh0stwizard

Тем не менее, мапить файл рано или поздно придется, когда внезапно понадобиться 50 000 или 100 000 координат

Лол, просто девелопмент не для тебя, братиш.

anonymous ()
Ответ на: комментарий от superhackkiller1997

Лучше бы ты кресты так рекламировал, а то у меня уже отвращение к голому си появляется из-за адептов...

minakov ★★★★★ ()
Ответ на: комментарий от beastie

Старая BDB не сможет дать такой throughput, т.к. не может синкать отдельные записи. А без синка база обречена внезапную смерть. А с синком будут ощутимые тормоза (только по сравнению с обычными файлами, естественно). От синка данных может спасти журнал, который в новых версиях, но тащить этого оракловского монстрика ради записей в файле, я делаю хм.

Если запись редкая, а чтение частое, то стандартная и везде в наличии BDB 1.85/1.86 на BTREE или RECNO может быть очень хорошим решением.

anonymous ()
Ответ на: комментарий от minakov

Это будет последние, что я сделаю в своей жизни.

А что с адептами нитак? Реальные адепты сишки просто не любят юзать 10к строк на то, что можно сделать 3-мя.

superhackkiller1997 ()
Ответ на: комментарий от Norgat

автор получит 5000 файлов. Нафига это нужно?

1) экономия на спичках. Что такого в 5тыщ файлов?

2) гораздо проще для обновления. У тебя имя файла это нужная дата.

В общем, не надо все данные в один файл сливать.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

Ломаются и тормозят файловые системы вроде нтфс, а также переполнение глоббинга в shell со товарищи. Можно поделить на директории по тыще штук, тогда везде будет ок.

anonymous ()
Ответ на: комментарий от superhackkiller1997

реальные адепты не будут с пеной у рта доказывать что-то недоучившимся и людям в процессе обучения, а тихо-мирно подскажут направление и все, посадив семя знаний и наблюдая как растет ЧСВчеловек. А тремя и на баше можно писать.

2ТС: Я бы тоже в файле сделал, так как БД, по мнению моей логики следует пихать для списков всяких. Но, возможно, я не прав - учусь сам

minakov ★★★★★ ()
Ответ на: комментарий от anonymous

а также переполнение глоббинга в shell со товарищи

Это уже давно не актуально.

Можно поделить на директории по тыще штук, тогда везде будет ок.

Здравая мысль. Причём, можно разбить по дням/месяцам и получится что-то типа индекса. Заодно можно будет удобно удалять старые данные.

true_admin ★★★★★ ()
Ответ на: комментарий от minakov

Дак я сказал нормально, что я не вижу смысла в том, что писали до меня.

А уже тот спор поднял не я, а всякие доказыватели мне их ООП истин, поэтому зачем ты на меня гонишь? Я лишь написал объективно самое простое, быстрое и надёжное решение.

superhackkiller1997 ()
Ответ на: комментарий от true_admin

Нинай, у меня греп вот что выдает:

./limits.h:68:#define	_POSIX_ARG_MAX		4096
./sys/param.h:102:#define	NCARGS		ARG_MAX		/* max bytes for an exec function */
./sys/syslimits.h:75:#define	ARG_MAX		   (256 * 1024)	/* max bytes for an exec function */

А вот здесь почти везде счет идет на десятки килобайт. Хотя в рамках задачи это не актуально, согласен.

anonymous ()
Ответ на: комментарий от true_admin

Причём, можно разбить по дням/месяцам и получится что-то типа индекса. Заодно можно будет удобно удалять старые данные.

Но зачем городить такой велосипед если есть SQLite? Табличка с матрицами + сколько душе угодно табличек с метаданными (если и когда будут нужны) и не нужно заморачиваться с созданием папок, подсчётом количества файлов в папке и разруливанием проблем с файловыми системами, если таковые появятся (а с файлами в несколько десятков гигабайт вроде все ФС легко справляются).

Norgat ★★★★★ ()
Ответ на: комментарий от Norgat

разруливанием проблем с файловыми системами, если таковые появятся

о каких таких мифических проблемах вы все говорите? Кстати, а sqlite вообще repair database есть?

true_admin ★★★★★ ()
Ответ на: комментарий от anonymous

у меня греп вот что выдает

Сюрприз:

ux32vd@test$ for x in `seq 100000`; do touch $x; done
^C
ux32vd@test$ ls | wc -l
36360
ux32vd@test$ rm *
ux32vd@test$ ls -la
total 0
drwxr-xr-x  2 exe  exe   40 May 28 13:28 .
drwxrwxrwt 11 root root 380 May 28 13:27 ..

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

о каких таких мифических проблемах вы все говорите?

1) Фрагментация из-за большого кол-ва мелких файлов. Как результат - замедление скорости доступа к данным на HDD накопителях (тут всё зависит от конкретной ФС и её особенностей).

2) Некоторые ФС плохо работают с большим кол-вом небольших файлов, т.к. дописывают кучу метаинформации. На ЛОРе были даже были темы про это (искать лень, было год или полтора назад вроде). Получим оверхед по размеру данных пропорционально количеству файлов.

3) Придётся писать свой велосипед, пусть и небольшой. А, следовательно, искать и править в нём баги. В случае использование элементарного SQLite часть багов за нас уже выловлена и пофикшена (особенно учитывая то, что Firefox юзает SQLite, а, следовательно, «тестеров» у SQLite более чем достаточно). Лично мне лень тратить своё время на решение данной задачи. Зачем? Есть уже готовое решение, да ещё и протестированное.

Кстати, а sqlite вообще repair database есть?

Если я правильно тебя понял, то предлагается делать это через .dump. Примерно так: http://www.ibiblio.org/elemental/howto/sqlite-backup.html

Если я тебя неправильно понял, то поясни, что ты имел ввиду под repair database.

Norgat ★★★★★ ()
Ответ на: комментарий от Norgat

1) а база данных, стало быть, не будет фрагментироваться? А ничего что она тоже файл?

2) «некоторые ФС плохо работают с большим кол-вом небольших файлов» — ты что, издеваешься? Ну не используй эти «некоторые ФС». Или тебя насильно заставляют ставить какой-нить фат16? Все основные ФС отлично работают с 5тыщ файлов. В продакшене я следующие ФС видел/использовал: рейзер3, xfs, ext2, ext3, ext4, jfs, tmpfs.

3) Путь ТС сам выбирает как ему удобнее. Но вот у меня нет никаких проблем написать «велосипед» из 10 строчек:

def get_data(year, month, day):
  try:
    fname = '{year}/{month}/{year}{month}{day}.dat'.format(**locals())
    with open(fname) as f:
      return f.readall()
  except FileNotFound:
    ..
  except Exception as err:
    raise Exception("%s"%err)

Если я правильно тебя понял, то предлагается делать это через .dump.

В том-то и дело что ты говоришь про «ненадёжность фс», а сам никогда не восстанавливал битую sqlite-базу.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

1) а база данных, стало быть, не будет фрагментироваться? А ничего что она тоже файл?

Тут я неправильно выразился. В случае с одним файлом - дефрагментация спасёт мир, но если их куча мелких, то данные могут быть размазаны по всему разделу несмотря на профедённую дефрагментацию.

Все основные ФС отлично работают с 5тыщ файлов.

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

Путь ТС сам выбирает как ему удобнее.

Согласен. Каждый из нас всёравно выберет то, что ему удобней использовать.

Norgat ★★★★★ ()
Ответ на: комментарий от Norgat

В случае с одним файлом - дефрагментация спасёт мир

Увы, для самой мейнстримовой ФС дефрагментатора вообще нет. А так тут три нюанса:

1) виндовые дефрагментаторы, например, умели в том числе дефрагментировать свободное место.

2) у меня есть сомнения что проблемы производительности вообще актуальны. 1) при данных объёмах всё легко закэшируется в оперативе 2) нам ничего не известно о запросах. Может старые данные будут редко запрашиваться. 3) может там два запроса в день прилетает

3) я бы воткнул ssd и не парился.

true_admin ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.