Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Добавление json данных в базу


Автор: stalker2000 7.12.2015, 00:43
Добрый день. Некий скрипт в цикле делает некие действия и по результату формирует массив для одиночного результата. Далее, этот массив записывается в базу в json формате. В новой итерации цикла формируется новый массив, который должен быть добавлен к тому, что уже хранится в базе. В коде это выглядит так:
Код

for($n=0; $n<=10000; $n++) {
  //  тут какие-то операции, по результатам формируется
  $v = array(/* тут результаты */);

  // получаю то что было записано в базу раньше
  $result_archive_json = DB::dbv('SELECT json_results FROM archive WHERE id=?', $id);
  $_v = json_decode($result_archive_json, 1);
  
  // добавляю новые результаты к существующим
  $_v[] = $v;

  // записываю новый массив в базу
  $new_result_archive_json = json_encode($_v, JSON_UNESCAPED_UNICODE);
  DB::dbq('UPDATE archive SET json_results=? WHERE id=? LIMIT 1', $new_result_archive_json, $id);
}

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

Автор: ksnk 7.12.2015, 08:19
Как часто и зачем будут использоваться эти данные?

К примеру, можно не склеивать данные сразу, а отложить это на потом.
json - это всегда одна строка. Можно просто приписывать следующий результат, через символ "\n" с помощью CONCAT. Тогда склеивать массивы придется только при использовании данных. Получить значение, порезать его на строки, раскодировать каждую, склеить массивы...

Автор: Envy 8.12.2015, 14:15
Я бы вообще отказался от варинта "писать json в БД". Сущности, из которых состоит массив, нельзя сохранить в отдельной таблице? Это решит вопрос, имхо.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Dobavleniye-json-dannykh-v-bazu-id5664ac60ae2015f00b8b4567#findElement_E7045_5666bbd8ae2015ff063b6061_0

Автор: Vas 9.12.2015, 08:52
Таблица и так массив. Добавляйте/удаляйте записи как обычно. А если получить json, выбирайте из БД массивом нужные строки по какому-то критерию и кодируйте в json.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Dobavleniye-json-dannykh-v-bazu-id5664ac60ae2015f00b8b4567#findElement_E7045_5667c191ae20152a073b6520_0

Автор: stalker2000 9.12.2015, 17:34
Цитата(ksnk @  7.12.2015,  08:19 Найти цитируемый пост)
Как часто и зачем будут использоваться эти данные?

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

Цитата(Envy @  8.12.2015,  14:15 Найти цитируемый пост)
Я бы вообще отказался от варинта "писать json в БД". Сущности, из которых состоит массив, нельзя сохранить в отдельной таблице? Это решит вопрос, имхо.

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

Подумал, можно попробовать использовать временную таблицу типа MEMORY, писать туда по одному параметру, а по окончании собрать и записать результат в постоянную таблицу. В таблицах типа MEMORY, кажется, есть ограничение на размер? 16 мб, если не ошибаюсь?

Автор: ksnk 9.12.2015, 17:56
Если не часто - то можно и моим способом, склеивая промежуточные json'чики.
При первом использовании, explode по символу перевода строки, собираем результирующий массив, потом сохраняем его в том же месте в таблице, чтобы не переклеивать его в следующий раз.
Можно каждый промежуточный json сохранять в новой строчке, с ID и датой вставки. Дата - чтобы при сборке данные не мешались. При первом использовании запись также можно склеить и сохранить одной строкой, вместо пучка.

Memory, вроде как, не поддерживает тип поля TEXT, так что хранить логи в памяти может и не получится. 


Автор: stalker2000 10.12.2015, 14:48
Цитата(ksnk @  9.12.2015,  17:56 Найти цитируемый пост)
Memory, вроде как, не поддерживает тип поля TEXT, так что хранить логи в памяти может и не получится. 

Так и есть. Ладно, спасибо всем, что-то буду думать.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)