Лучший способ сохранить данные массива PHP в таблицу MySQL - PullRequest
6 голосов
/ 31 декабря 2011

Мой вопрос - какой самый лучший и эффективный способ сохранить большой массив php в таблицу mysql.Я знаю, что есть много способов сделать это, и я попробовал несколько из них, но я все еще не нашел метод, который мне действительно удобно использовать.Основной метод, который рекомендует большинство людей - это php-функции serialize () и unserialize ().По какой-то причине это не работает для меня, и я, кажется, пытался исправить это, но idk.

Вот мой код:

    // unserialize songs, add new song to end of array, and then re-serialize to add to db
    $cereal = unserialize($dbsongs);
    $pushed = array_push($cereal, $_GET['song']);
    $songs = serialize($pushed);

    //update playlists table
    $stmt = $dbh->prepare("UPDATE playlists SET songs=:songs WHERE title=:title AND user=:user");
    $stmt->bindParam(':user', $_SESSION['username'], PDO::PARAM_STR);
    $stmt->bindParam(':title', $_GET['title'], PDO::PARAM_STR);
    $stmt->bindParam(':songs', $songs, PDO::PARAM_STR);
    $stmt->execute();

Итак, сначала я отменяю серию $ dbsongs , который является пустым списком сериализованных данных из таблицы MySQL.Затем я помещаю $ _ GET ['song'] в массив с помощью array_push () .Затем я сериализирую это и сохраняю в БД.По некоторым причинам это не работает, но я также хотел бы знать, если есть лучший способ.

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

Или я должен просто исправить этот метод, который я использую?Или даже добавить base64_decode () и base64_encode () ?Эти методы кажутся довольно старыми из-за того, что я читал ... http://www.evolt.org/node/60222

Я видел метод, использующий .implode , но я не могу понять, как его использовать ... Ссылка 1 Ссылка 2 .Это выглядит как самый современный подход, который я видел.Это то, что я должен изучить дальше?

Не уверен, что это за метод, но он упоминает Cakephp, который, я полагаю, является библиотекой php.Это хороший метод? Ссылка 1

Я собираюсь хранить много элементов в этих списках (например, более 1k элементов регулярно), поэтому я даже не уверен, что еслисохранение этих элементов в одном поле таблицы будет целесообразным.Будет ли просто создание таблицы для этих элементов лучшим способом, так как список будет очень длинным (создание новой записи в БД для каждого добавленного нового элемента и создание поля «заголовок», чтобы связать их все вместе)?Я никогда не экспериментировал с чем-то подобным, потому что я никогда не мог найти достаточно информации о том, сколько данных может на самом деле хранить mysql без проблем.

Я знаю, что здесь много вопросов, но любые ответы будут с благодарностью приняты!Заранее спасибо!

-BAH

1 Ответ

12 голосов
/ 31 декабря 2011

Во-первых, позвольте мне сказать, что serialize() - это путь, если вы хотите хранить массивы PHP в БД.

Ваша проблема в том, что вы неправильно использовали array_push().Если вы используете его правильно, метод serialize () будет работать.Я сейчас расскажу, как исправить ваш код для этой цели.

Использование сериализации и хранения сериализованных имен песен в одном поле TEXT на самом деле идеально здесь, потому что это делает поиск по индексу FULLTEXT очень простым (ям при условии MySQL).Например, вы можете легко найти все списки с названиями песен, содержащими слово «удивительный», когда храните сериализованный массив в одном поле.

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

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

ПОЧЕМУ СЕРИАЛИЗАЦИЯ НЕ РАБОТАЕТ С ВАМИ ПРЯМО СЕЙЧАС ...

array_push() возвращает целое число, и первый полученный параметр передается по ссылке.Это означает, что строка:

$pushed = array_push($cereal, $_GET['song']);

фактически устанавливает $pushed равным количеству элементов в массиве $cereal плюс один.

Вы можетеисправьте свою проблему следующим образом:

$serial = unserialize($dbsongs);
$song_count_in_pushed_array = array_push($serial, $_GET['song']);
$songs = serialize($serial);

ОБНОВЛЕНИЕ

В ответ на ваш комментарий о кодировке сериализованных данных в base64, вот как вы можете это сделать, чтобы предотвратить повреждение данныхс данными, которые не являются 8-битными чистыми:

// For safe serializing
$encoded_and_serialized = base64_encode(serialize($array));

// For unserializing
$restored = unserialize(base64_decode($encoded_and_serialized));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...