За последние 24 часа нас посетили 23094 программиста и 1238 роботов. Сейчас ищут 883 программиста ...

Добавление данных в БД.

Тема в разделе "PHP для новичков", создана пользователем AlexandrS, 5 фев 2019.

  1. AlexandrS

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

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    Структура БД:
    ID | DATA | NUMB

    id - автоинкримент и PK
    data - некая строка данных (UNIQ)
    numb - расчетное значение


    Идея такова, что значение data должно быть уникально, но если такое значение существует, тогда нужно numb увеличить на еденицу, если не существует то добавить и присвоить numb = 1

    И тут ка бы сам вопрос, как правильно построить логику, т.к. я, только изучаю БД, поэтому могу ошибаться в идее самом ответе (поведении) БД.

    Т.к. графа data уникальна, то при попытке добавить туда не уникальное значение возникнет ошибка, если работать через PDO с настройкой
    PHP:
    1. setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    в лог будут лететь исключения и как я понимаю данный подход не верен, т.к. я потенциально создаю ошибки.

    Другой вариант это работать через SELECT т.е. предварительно пытаться найти data и если данного значения нет, то записывать его, если есть то значение графы numb увеличивать на единицу.
    Что-то типа:
    PHP:
    1. $db->query("UPDATE `nameTable` SET `numb` = `numb` + 1 WHERE `data`= $dataString");
    Но сдается мне что данная реализация кривая и должен существовать более элегантный способ реализации.
     
    #1 AlexandrS, 5 фев 2019
    Последнее редактирование: 5 фев 2019
  2. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.794
    Симпатии:
    650
    INSERT... ON DUPLICATE KEY UPDATE...
     
    AlexandrS нравится это.
  3. AlexandrS

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

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    Благодарю!
     
  4. AlexandrS

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

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    При каждом запросе типа
    INSERT... ON DUPLICATE KEY UPDATE...
    PK при AUTO_INCREMENT увеличивается, даже если фактически не происходило добавления, с этим как-то можно бороться?
    Ибо при при большом количестве обращений можно и BIGINT заполнить :)
    А PK необходим для связки с другими таблицами.
     
  5. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.794
    Симпатии:
    650
    В общем это норм. Конкретно тут наверно InnoDB «чудит». В доках должно быть об этом написано.
    --- Добавлено ---
    Если сильно критично, попробуйте MyISAM использовать. Но, повторяю, на такие «мелочи» не стоит обращать особого внимания.
     
    AlexandrS нравится это.
  6. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Нормальная реализация. С индексом будет быстро работать и не будет увеличивать инкремент.
     
    AlexandrS нравится это.
  7. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.794
    Симпатии:
    650
    SELECT хорош для предварительных действий. В последовательном коде обычно сразу пытаются сделать изменение и смотрят на результат.
     
    AlexandrS нравится это.
  8. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    D MySQL ещё есть REPLACE, вроде он не изменяет автоинкремента у существующих строк
     
    AlexandrS нравится это.
  9. AlexandrS

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

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    А где вообще можно посмотреть все существующие SQL команды? Т.к. в имеющейся литературе, да и в примерах в сети всё основано на нескольких основных командах. Всё для более менее интересной реализации требует поиска ответов на вопросы в форумах и чатах.
     
  10. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    #10 mkramer, 6 фев 2019
    Последнее редактирование: 6 фев 2019
    AlexandrS нравится это.
  11. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.794
    Симпатии:
    650
    --- Добавлено ---
    Если не понятно, там ниже еще уточняется как раз для твоего случая:
    Т.е. при инкременте тек. значение нужно предварительно сохранять, поэтому опять приходим к «разрыву атомарности».
     
    AlexandrS нравится это.
  12. Зингер

    Зингер Активный пользователь

    С нами с:
    20 июл 2017
    Сообщения:
    127
    Симпатии:
    7
    Возможно, поможет использование транзакций (откат, фиксирование).
     
  13. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @AlexandrS, предположим, что обновление будет выполняться во много раз чаще, чем добавление.
    Следовательно, можно выполнить update, проверить количество задействованных строк и, если оно нулевое - выполнить вставку, отловить ошибку, если кто-то вдруг уже успел добавить именно эту запись и выполнить update.