Как хранить массив в mysql
Здесь могла бы быть ваша реклама
Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006
Откуда: Israel
Помог: 3 раз(а)
Секрет
Теперь, когда вы уже наверняка второпях отправили свой запрос,
я расскажу вам простой секрет, который сэкономит вам уйму ожиданий,
даже если первый ответ по теме последуем сразу же.
Само собой я знаю что ответят мне тут же, и если я посмотрю
на сообщения на форуме, то пойму что в общем то я и не ошибаюсь.
Но еще я точно замечу, что очень мало тем, в которых всего два ответа :
вопрос автора и еще два сообщение вида Ответ + Спасибо
После этого приходится начинать уточнять этим неграмотным что мне надо.
Они что, сами читать не умеют? А уточнять приходится.
И иногда пока они переварят то что я им скажу проходит и не одна ночь..
Уверен что если бы я им сказал что у меня есть
фиолетовый квадрат, и нужно превратить его в синий треугольник
и я пытался взять кисточку, макнуть в банку и поводить ей по квадрату
но почему то кисточка не принимала цвет краски в банке,
то на мой вопрос — где взять правильные банки мне бы ответили гораздо быстрее
предложив её открыть, а не тратить еще стольник на жестянку.
Поэтому с тех пор я строю свои вопросы по проверенной давным давно схеме:
Что есть
Что нужно получить
Как я пытался
Почему или что у меня не получилось.
На последок как оно происходит на форумах
Цитата:
Новичок: Подскажите пожалуста самый крепкий сорт дерева! Весь инет перерыл, поиском пользовался!
Старожил: Объясни, зачем тебе понадобилось дерево? Сейчас оно в строительстве практически не используется.
Новичок: Я небоскрёб собираюсь строить. Хочу узнать, из какого дерева делать перекрытия между этажами!
Старожил: Какое дерево? Ты вообще соображаешь, что говоришь?
Новичок: Чем мне нравиться этот форум — из двух ответов ниодного конкретного. Одни вопросы неподелу!
Старожил: Не нравится — тебя здесь никто не держит. Но если ты не соображаешь, что из дерева небоскрёбы не строят, то лучше бы тебе сначала школу закончить.
Новичок: Не знаите — лучше молчите! У меня дедушка в деревянном доме живёт! У НЕГО НИЧЕГО НЕ ЛОМАЕТСЯ.
Но у него дом из сосны, а я понимаю, что для небоскрёба нужно дерево прочнее! Поэтому и спрашиваю. А от вас нормального ответа недождёшся.
Прохожий: Самое крепкое дерево — дуб. Вот тебе технология вымачивания дуба в солёной воде, она придаёт дубу особую прочность:
Новичок: Спасибо, братан! То что нужно.
Отредактировано модератором: Uchkuma, 26 Апреля, 2011 — 10:21:12
Как хранить массивы в базе данных?
Есть PHP скрипт. Генерируется массив. Каким образом можно хранить его в базе данных(MySQL) дабы при обращении было легко им манипулировать? И что, если массив состоит из других массивов? Хотелось бы увидеть небольшие примеры кода, или в крайнем случае, ссылки, что можно использовать. Спасибо.
Array ( [grounds] => Array ( [1] => Array ( [date] => 2014-05-28 [timeStart] => 8:45 [timeEnd] => 9:45 [groundId] => 1 [price] => 1500 ) [2] => Array ( [date] => 2014-06-4 [timeStart] => 8:45 [timeEnd] => 9:45 [groundId] => 2 [price] => 1800 ) ) [count] => 2 [summ] => 3300 )
- Вопрос задан более трёх лет назад
- 35027 просмотров
Комментировать
Решения вопроса 2

Алексей Кулешов @GingerbreadMSK
1. serialize/unserialize (для хранения в БД самое то)
2. JSON (если нужен обмен через AJAX без преобразований)
Ответ написан более трёх лет назад
Нравится 7 2 комментария

Дмитрий @another_dream Автор вопроса
serialize подойдет для ассоциативного массива, в который вложено еще пару таких же?

Алексей Кулешов @GingerbreadMSK
Как в MySQL засунуть массивы?
php: serialize / unserialize
все так в основном делают.
#2
13:22, 31 июля 2005
Dexus
спасибо 🙂
#3
13:51, 31 июля 2005
wat
Пожалуйста 🙂
но на самом деле и split/join с запятыми (или какими-нибудь ддругими спец-символами) тоже — неплохой метод.
Serialize/unserialize — для чего-то более структурно-сложного, чем просто одномерный массив.
#4
14:20, 31 июля 2005
wat что-то замышляет.
определенно.
А запихнуть — смотря какой массив.
Вопервых надо подумать — а стоит ли. Одно дело, если массив фиксированого размера, тогда порядок, но если нет, то встает вот какая проблема: если в sql таблице есть поля с произвольным размером (text или blob, а последний — какраз для хранения таких вот сериализованых массивов), то скорость доступа к этой таблице значительно уменьшается.
Потом. Большие массивы опасны тем, что для доступа в скрипте к одному элементу придется выковыривать весь массив целиком (в память), а оттуда выковыривать нужный элемент. Надо очень долго шаманить, чтобы минимизировать ресурсоекость скрипта, работающего с этим массивом (еще больше шаманить надо, когда надо наладить работу несколькихз паралельных скриптов, тут уж без бубна совсем никак).
И последнее если массив маленький, и должен быть в каждой записи — а не заменить ли его полями, если массив большой и должен быть в каждой записи — не жалко ли места (не отказаться ли от него), если массив большой, и нужен далеко не в каждой записи — не завести ли доп. таблицу.
#5
14:56, 31 июля 2005
Что бы потом не гемороится, лучше сделать так: В ячейке сохранять имя отдельной таблицы, в которую уже можно поместить массив. Так по крайней мере, на тебя не будут давлеть ни какие ограничения. Имя таблицы может генерироваться автоматически (это просто связка префикс-ID, где префикс нужен для того что бы такие таблицы можно было легко визуально отделить от остальной БД).
Кста, при большом количестве и размере массивов ты так выиграешь в скорости.
- Sbtrn. Devil
- Постоялец
#6
15:08, 31 июля 2005
Или завести большую универсальную таблицу с полями (оба индексные): имя массива, индекс массива. + остальные поля, как данные ячеек массива. А ссылать на массив посредством указания его имени. Тут, по-хорошему, надо б ещё привлечь отношения таблиц 1много, но не всегда это может оказаться позволительно.
#7
15:21, 31 июля 2005
DimaSun
Согласен, лучше чуть-чуть сменить дизайн базы и воспользоватся преимуществами sql запросов. Но лучше для массивов сделать одну таблицу и дифферинциировать массивы по некому полю. (хотя конечно зависит от)
#8
16:12, 31 июля 2005
Массивы могут иметь разную размерность, тут не очень удобно получится.
#9
20:21, 31 июля 2005
DimaSun
Вот что я имал в виду. Например пользователю нужно сопоставить массив целых чисел, делаем что-то типа этого:
CREATE TABLE user_ints
( user_id INT NOT NULL,
value INT NOT NULL,
INDEX(user_id)
);
Если нужно, можно ввести колонку определяющую порядок значений (локально для пользователя или глобально для таблицы), время создания и т.п.
Если индексировать и value, то можно быстро удалять сами значения не перебирая всех пользователей.
#10
21:48, 31 июля 2005
Это хорошо. А если массив двумерный? А если их несколько (Вообще в БД), и они действительно разной размерности?
Я думаю мы оба правы, но рассматриваем несколько разные случаи. 🙂 Мы не знаем конкретной задачи.
#11
22:32, 31 июля 2005
у базы данных не бывает полей произвольного размера. TEXT например занимает фиксированно 32 килобайта
#12
23:04, 31 июля 2005
keltar
Фигю какую то ты сказал
В MySQL есть три вида текстового поля:
text — 2^16 байт (64К)
mediumtext — 2^24 байт (16Мб)
lolgtext — 2^32 байт (4Гб)
с блобами та же история.
Только это _максимальный_ размер поля.
База не будет резервировать по 16 мегабайт для каждого mediumtext поля, как и 65 кб для обычного текстового. БД динамично места выделяет.
#13
9:29, 1 авг 2005
Если MySQL использовать из C++ с Unix компилятором gcc, то можно в поле TEXT, MEDIUMTEXT или LONGTEXT запихивать массив, как дам его памяти без serialize / unserialize, предварительно сделав addslashes.
А в PHP числа в переменных в наглую приводятся к текстовой записи, что часто не удобно.
Если массив короткий, то можно сделать в php числа через ‘;’ или ‘,’ в виде строки текста, как Wat написал. Но если нужно хранить огроменные массивы, то php’шный serialize на столько увеличивает память для его хранения, что #$#@@.
Чтобы предварительно писать скрипты на C++ под виндой в Microsoft Visual Studio и с MySQL, нужно скачать полную версию MySQL под винды с частью интерфейсных файлов C++, файлом mysql.h . Его можно подключать и юзать MySQL в сях. Если не использовать подключение нестандартных библиотек, то обычно отлично компилится написанная прога и под Unix. Только нужно запускаемый скомпилленый бинарный файл в Unix переименовать в *.cgi и поставить права, как у cgi перловских скриптов и под многими хостингами с разрешённым исполнением бинарников отлично работает.
Другой способ, но много памяти хавает — как уже описали. Создать отдельную таблицу с полями
CREATE TABLE table_array
(
parentId INT, — ссылка на id родителя, которому принадлежит массив
value INT, — значение одного из элементов массива
PRIMARY KEY (parentId, value)
)
Массив можно получать
SELECT value FROM table_array WHERE parentId = $myParentId
#14
9:50, 1 авг 2005
Volodya
Мне думается что хранить массив в бинарном виде в PHP тоже можно. делать подобную «упаковку», если это те же числа.
по типу charint=chr((number>>24)&255).chr((number>>16)&255).chr((number>>8)&255).chr(number&255).
в обратную сторону преобразовывать через ord()
Как хранить массивы в базе данных
При работе с базой данных MySQL иногда нужно сохранить массив в одном поле. К сожалению, нет способа непосредственно передать массив как параметр. В результате, хранение таких структур данных становиться более сложным процессом, но, тем не менее, возможным.
Чтобы конвертировать любой массив (или объект) в строку в PHP, нужно вызвать функцию serialize:
$array = array( 1, 2, 3 );
$string = serialize( $array );
echo $string;
$string содержит строчную версию массива. Выше приведенный пример выведет следующее:
Чтобы конвертировать такую строку обратно в массив, надо использовать unserialize:
// $array будет содержать( 1, 2, 3 )
$array = unserialize( $string );
Теперь проведём конвертацию массива из 200 случайно генерированных целых чисел в диапазоне от 1 до 1000:
$array = array(); 2 for( $i = 0; $i < 200; $i++ )
$array[] = mt_rand( 1, 1000 );
$string = serialize( $array );
echo $string;
Пример выведет подобную строку:
Данная строка может быть сохранена в базе данных и конвертирована в массив по мере надобности. Очень часто функция base64_encode используется в сочетании с функцией serialize для хранения массивов:
$string = base64_encode( serialize( $array ) );
Зашифрованная строка может быть восстановлена в массив с помощью функции base64_decode:
$array = unserialize( base64_decode( $string ) );
К сожалению, такие строки могут иметь очень большой размер. В таком случае можно использовать функцию gzcompress для сжатия строки (размер сжатой строки существенно меньше):
$smallString = gzcompress( $string );
Перед использованием, такую строку надо вернуть к обычному виду с помощью функции gzuncompress.