За последние 24 часа нас посетили 22839 программистов и 1267 роботов. Сейчас ищут 803 программиста ...

Хранение массива значений в одном столбце vs. для каждого значения свой столбец

Тема в разделе "PHP для новичков", создана пользователем 118_64, 6 июн 2019.

  1. 118_64

    118_64 Активный пользователь

    С нами с:
    8 янв 2015
    Сообщения:
    84
    Симпатии:
    2
    Есть таблица со значениями: id, title, description.
    И есть набор значений, который необходимо хранить в таблице, что можно сделать двумя способами:

    1. В виде сериализованной строки: '{"a":1,"b":2,"c":3}' в поле description, которую затем разбирать
      PHP:
      1. $arr = json_decode($json, true); $a = $arr[0]; $b = $arr[1]; $c = $arr[2];
    2. Добавить в таблицу три столбца, в каждом из которых хранить в виде строки значения, соответственно, для $a, $b, $c, и которые в дальнейшем можно запрашивать и использовать без необходимости декодирования и получения в виде значения массива.
    По ряду причин для меня более приемлемым является первый вариант. Одна из причин - нет ограничений на количество вариантов значений: хоть три, хоть десять элементов можно хранить в виде сериализованной строки, а затем получать в качестве элемента массива, чего я буду лишён, если количество значений будет задано имеющимися столбцами таблицы.

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

    Прошу совета, насколько расточителен (или нет?) первый вариант хранения данных с двойным преобразованием перед использованием? Есть какие-то общепринятые подходы в подобных случаях?
     
  2. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @118_64, можете ответить всего на один вопрос? Для чего нужна База Данных, не в вашем конкретном случае, а если мыслить глобально?
     
  3. 118_64

    118_64 Активный пользователь

    С нами с:
    8 янв 2015
    Сообщения:
    84
    Симпатии:
    2
    Могу дать ответ из Википедии. Лично мне нужна для хранения данных эффективным способом, под которым я понимаю некое сочетание производительности и вариативности хранимых данных.
     
  4. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    База данных нужна для ОБРАБОТКИ информации, хранение данных в БД - это всего лишь приятный бонус. А вот того что бы обрабатывать эти самые данные их надо хранить в подобающем виде.
    Почитайте про нормализацию баз данных. К примеру ваш первый вариант это прямое нарушение первого закона нормализации.
    Если есть непреодолимое желание хранить данные в таком виде, то лучше использовать NoSQL базы данных.
    Ваш второй вариант (правильный вариант) - это классика жанра. Ну и в конце концов БД умеет хранить данные в JSON формате, но обработка в таком виде хуже чем при классическом варианте.
     
    118_64 нравится это.
  5. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    @118_64 таблица description :
    Код (Text):
    1. id   | name
    2. 3131 | a
    3. 3462 | b
    4. 4436 | c
    5. 3456 | d
    6. 7451 | e
    7. 3109 | f
    таблица2:
    Код (Text):
    1. id      | title    | description_id | sum
    2. 231231  | название | 3131           | 1
    3. 321332  | название | 3462           | 2
    4. 565563  | название | 4436           | 3
    --- Добавлено ---
    да нормально тут все
    PHP:
    1. select des.name, sum
    2. from table2 as t
    3. left join description  as des on des.id = t.description_id
    4.  
    5. $result = [{'name' => 'a', 'sum' = '1'}, {'name' => 'b' ,'sum' => '2'}, {'name' => 'c' , 'sum' => '3'}];
     
    118_64 и Valick нравится это.
  6. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Artur_hopf, только указывай в следующий раз связь или поля идентификаторов именуй одинаково.
     
  7. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    @118_64 если потом из результата запроса хотите сделать массив как у вас, то так можно:
    PHP:
    1. $result = [ ['name' => 'a', 'sum' => '1'], ['name' => 'b' ,'sum' => '2'],['name' => 'c' , 'sum' => '3'] ];
    2.  
    3. $arr = [];
    4. foreach($result as $item){
    5.     $arr[$item['name']] = $item['sum'];
    6. }
    7. print_r($arr);
     
    118_64 нравится это.
  8. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.752
    Симпатии:
    1.322
    Адрес:
    Лень
    еще мона, но не комельфо
    PHP:
    1. $result = ...
    2.  
    3. print_r ( array_combine ( array_column ( $result, 'name' ), array_column ( $result, 'sum' ) ) );
     
  9. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.752
    Симпатии:
    1.322
    Адрес:
    Лень
  10. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Как там в 2010?

    https://postgrespro.ru/docs/postgrespro/11/datatype-json
     
  11. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @romach, а если внимательно перечитать сообщение?
     
  12. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Ну, пробуем перечитать.

    JSON в базе - это не что-то новое или нестандартное, в том же pgsql jsonb (не json) существует с 2014 года, активно развивается и многими используется. По нему делаются выборки, строятся индексы, при чем при желании очень хитрые индексы позволяющие дешево делать выборки напрямую под ключам / массивам в значении поля.

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

    И да, уходить от нормальной формы - это может не самая лучшая, но и не самая редкая практика.

    Чем?
     
  13. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @romach, тем, что по умолчанию если не оговорено иное БД это MySQL. Вы можете сколь угодно долго цепляется к моим словам, а можете объяснить ТС данный материал как считаете нужным.
    Маленькому ребёнку гораздо проще показать на коробок спичек и сказать нельзя, чем долго и нудно приводить примеры из жизни подкрепляя свои слова статистикой пожаров. Придёт время и он поймёт, что к чему. Примерно такая же ситуация с начинающими программистами.
     
  14. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    В mysql всё это тоже есть, применяется и используется. С несколько другим подходом, с которым я на практике особо не знаком (и потому сослался на pgsql), но всё же.
    Ну так я и привел альтернативное мнение. Объяснять подробно смысла не вижу, всё это подробно описано в документации и куче статей. ТС захочет - прочитает, теперь у него хотя бы есть выбор.
     
  15. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Неудобство поиска, сортировки, фильтрации содержимого json разве не очевидно?
     
  16. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @romach, я знаю что есть, поэтому и написал об этом третьим пунктом. А то что реляционной бд (включая и pgsql) сложнее работать с противоестественным для нее форматом, коим является json, то я тут при чём? Первый вариант ТС это хранение неатомарных данных в поле с типом varchar. Поэтому я и посоветовал nosql решения.
     
  17. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Чем сложнее то? Дополнительным синтаксисом?
     
  18. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
  19. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Только вот контексты разные. Там json-поле не к месту, тут - к месту, потому что если взять из тех ответов все верные аргументы (ну, "у json нет индекса потому медленно-медленно" - это не серьезно), то окажется что они применимы там и весьма спорны тут.

    Впрочем, дискутировать на такие темы - скучно, разве что синтетику запилить по быстрому для наглядного сравнения.
     
  20. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Да можно например наглядно сравнить как сделать поиск с like по атрибуту json и нормализованному столбцу в mysql.