Задать вопрос
Профиль пользователя заблокирован сроком с 10 апреля 2022 г. и навсегда по причине: систематические нарушения правил сервиса
Ответы пользователя по тегу MySQL
  • Mysqli - как исправить ошибку с bind_param?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Перед коннектом к mysqli пишем волшебную строчку
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

    и выясняем, какая проблема была с нашим запросом
    Ответ написан
    Комментировать
  • Mysqli - multi_query - как правильно использовать?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Какой-то странный пример.
    Обычно примеры выглядят по-другому.
    строчка
    if (!$mysqli->more_results()) {
    позволит что-то вывести только если все результаты (и их ошибки!) уже кончились. Поэтому, в упрощенном варианте её надо просто убрать,
    if ($mysqli->multi_query($toadd)) {
        do {
                echo 'Insert ' . $i . ' Error: ' . $mysqli->error . '<br />';
        } while ($mysqli->next_result());
    }

    а в каноническом - добавить в условие while.

    Смысла выполнять мультизапросы, действительно, немного. В 99.999% случаев одинарные запросы лучше.
    Если только УЖЕ есть готовый дамп - тогда имеет смысл применять эту функцию. Специально же собирать запросы в кучу не нужно.
    Ответ написан
  • Как исправить ошибку после установки phpmyadmin?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Let me google that for you, helpless baby: https://www.google.ru/search?q=Fatal+error:+Call+t...
    Ответ написан
    Комментировать
  • Как парсить курс валют и записывать в БД?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    если не трудно, приведите свой пример.

    include 'safemysql.class.php';
    $db = new safeMysql();
    $sql = "INSERT INTO btc_charts_live SET mark = 'btce', date=NOW(), ?u";
    $db->query("INSERT INTO btc_charts_live SET ?u", $btc);

    Хотя, чтобы понять, как это работает и почему важно делать только так, а не иначе, даже начальных знаний недостаточно, даже не говоря об отсутствии знаний вообще.
    Ответ написан
  • Почему поле БД увеличивает только 1 раз?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Это типичная ошибка похапе программистов, которые пишут код методом копирования, не подключая голову.
    values(field) для них - не команда, выполняющая строго определённую функцию, а священный текст, завещанный предками, кототорый надо употреблять только так и никак иначе, потому что он составляет часть Великой Мантры Он Дупликейт.

    А если дать себе труд подумать, что делает эта функция, то нужное решение тут же придёт в голову, поскольку является частью Мантры Инкремента Значения Поля.
    Ответ написан
    Комментировать
  • Каталог с сортировкой: как решить проблему при выводе с сортировкой?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    если данные атрибутов находятся сериализованные в базе в таблице option,

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

    Потом перепроектировать базу.
    Сделать категории в нормальной таблице, приджойнить к запросу и сортировать по ним.
    Ответ написан
    1 комментарий
  • Как на PHP составить MySQL SELECT из двух таблиц одновременно с 2-мя массивами в запросе и условием?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    сами таблицы очень похожи, разница только в названии одного из полей

    <font size=+100500>ТАБЛИЦА ДОЛЖНА БЫТЬ ОДНА</font>
    Ответ написан
    Комментировать
  • Как исправить ошибку "mysql client library is not bundled anymore"?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    mysqli надо собирать так
    --with-mysqli=mysqlnd
    Ответ написан
    Комментировать
  • Можно ли как-то вернуть уже типизированный результат без лишних действий?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Да, можно. Надо юзать mysqli или PDO с поддержкой mysqlnd.
    Причем в этом случае можно будет получить от базы даже NULL - чего никаким ручным кастингом не сделаешь.

    Правда, в mysqli для этого надо использовать prepare - mysqli_query() типы не возвращает. А подготовленное выражение - да:
    $stmt = $db->prepare("SELECT NULL, 1, 's'");
    $stmt->execute();
    $res = $stmt->get_result();
    $row = $res->fetch_assoc();
    var_dump($row);

    array(3) {
      ["NULL"]=>
      NULL
      [1]=>
      int(1)
      ["s"]=>
      string(1) "s"
    }
    Ответ написан
    Комментировать
  • Какой код лучше использовать, чтобы отлавливать ошибки MySQL?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Если выбирать из этих двух, то второй, разумеется. Он на порядок лучше первого:
    - в отличие от первого, он будет выдавать ошибки туда же, куда и весь остальной РНР. На машине разработчика это может быть экран, на боевом сайте - лог. Первый плюёт ошибки в браузер ВСЕГДА, чего на боевом сайте не должно быть никогда
    - в отличие от первого, он сообщит номер строки и имя файла, где произошла ошибка, что является критически важным для того самого отлова ошибки. Рекомендую попробовать поискать ошибочный запрос в коде на пару тысяч строк по сообщению от первого варианта. Подробнее про то, как правильно обрабатывать ошибки, можно почитать здесь: Обработка ошибок, часть 1

    Примечание: на самом деле ни тот, ни другой коды работать не будут, поскольку mysqli_error() тоже требует $link в обязательном порядке.

    Дальше уже идут более продвинутые варианты.
    Для начала, mysqli умеет кидать исключения из коробки:
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

    и после этого любая ошибка mysqli будет порождать исключение.
    Но у этого подхода есть два минуса:
    1. Такой вариант может понадобиться только в случае, если обращения к mysqli_query разбросаны по всему коду, чего делать нельзя ни в коем случае.
    2. В брошенном исключении будет отсутствовать сам запрос, который может быть очень полезен при отладке.

    Поэтому идеальным вариантом будет такой:
    Во-первых, все обращения к mysqli API в обязательном порядке надо завернуть в какую-либо библиотеку, которая возьмёт на себя выполнение всей грязной и повторяющейся работы. Пример такой библиотеки - SafeMysql
    Во-вторых, в этой библиотеке оформить код обращения к mysqli_query такм образом:
    $res = $link->query($query);
    if (!$res) throw new Exception($link->error() ." [$query]");

    В результате мы получим идеальную обработку ошибок:
    - этот код уже из коробки будет так же следовать настройкам РНР, и не будет выдавать ошибки на экран на боевом сервере, но при этом программист всегда будет о ней проинформирован.
    - этот код будет выдавать трассировку вызовов - бесценную информацию, без которой найти место, где произошла ошибка, будет очень сложно.
    - брошенное исключение можно будет поймать в хендлере или блоке try..catch (однако если нет опыта работы с этими двумя вещами, то на первое время лучше оставить исключение как есть. В обработке ошибок есть много нюансов, неизвестных среднему кодеру, и поэтому лучше оставить эту задачу для РНР).
    Ответ написан
    Комментировать
  • PDO_MySQL: можно ли узнать наличие записей в result set'е без сдвига курсора?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Ерунда какая-то.

    те, которые действительно считали строки - это требуется и использовалось не часто, по-этому было благополучно за полдня переписано вручную на fetchAll + foreach

    Какое отношение к подсчету строк имеет foreach? count наверное имелся в виду?

    те, которые проверяли, есть ли строки в результирующем наборе (таких несколько сотен).

    а здесь как раз нужен fetchAll + foreach и проверка сведется к проверке результата fetchall.

    все вхождения mysql_num_rows

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

    А вы документацию читаете? Для select запросов не работает.


    Обновить документацию не пробовали? с 2004 года она могла немного поменяться. На худой конец можно попробовать и посмотреть самому. Это не так сложно, как кажется.

    ЗЫ: Я очень надеюсь, что речь идёт о подсчёте именно в резалтсете, а не в базе.
    ЗЗЫ:

    Все функции работы с БД были успешно переписаны за пару дней на PDO'шные путем замены имен функций регулярными выражениями по проекту

    - т.е., была проделана абсолютно бессмысленная, никому не нужная и совершенно бесполезная работа.
    Ответ написан
    Комментировать
  • Почему в PDO вопросительные знаки вместо русских букв при вставке данных в бд?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    "в бд заходят" - это не слишком корректное описание проблемы.
    Если все сделано именно так, как написано, то в БД входят нормальные символы. И надо тогда проверять, что при просмотре выбрана правильная кодировка.

    Но скорее всего всё-таки где-то в базе utf8 не указана. "Везде", кстати никакого значения не имеет. Важно только то, что стоит в описании таблицы/полей. Посмотреть можно через
    CREATE TABLE table_name
    Подробнее можно почитать здесь: Проблемы с кодировкой в MySQL
    К PDO эта проблема прямого отношения отношения не имеет.

    PS. Не принципиально, но лучше задавать кодировку в DSN, а не отдельным запросом
    Ответ написан
    3 комментария
  • Как сделать MySQL запрос, что бы получить сгруппированный массив?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    В некоторых похожих случаях можно посмотреть на group_concat()
    Но здесь, я думаю, стоит сначала получить рецепты, а потом отдельными запросами по ингредиентам и инструкциям, where recipe_id IN(..)
    Ответ написан
  • Как в MySQLi сделать поиск по параметрам, если их количество неизвестно?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    1. И сейчас можно, только надо делать по уму.
    Совсем не обязательно упираться в родные препареды. Их вполне можно эмулировать. Поэтому подключаем safeMysql и пишем для первого запроса
    $data = $db->getAll("SELECT * FROM t WHERE id IN (?a)", $params);
    а для второго
    $sql = "SELECT user_id,password FROM user WHERE email = ?s";
    $row = $db->getRow($sql, $email);
    2. if($result) не нужно было делать и раньше. Если база даёт сбой - это гарантированный фейл, и надо аварийно завершать работу. А не писать "что-то пошло не так" и продолжать долбить неработающую базу запросами.

    В отдельных исключительных случаях можно ловить исключение. Но именно как исключение, а не правило.

    Если работаем с голым mysqli (что не рекомендуется), перед коннектом надо написать вот это
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    и после этого ловить ошибки в error handler-е или блоке catch.

    3. Посмотрел повнимательнее. Это единственный из всех приведенных кейсов, в котором использование родных препаредов оправдано. В принципе - да, так и делать. Особо тут не ничего не придумаешь. Mysqli умеет биндить только переменные и только по ссылке. Для одноразового использования можно написать враппер, который будет биндить переменное число плейсхолдеров. Но вот для выполнения подготовленного запроса в цикле - только так. PDO же умеет биндить по значению, и позволяет немного сократить код
    foreach($array_1 as $id => $chtoto) {
        $stmt->execute([$id, $chtoto, $array_2[$i],$array_3[$i]]);
    }
    Как вариант, можно сформировать мультиинсерт опять же с помощью safeMysql:
    $ins = array();
    foreach($array_1 as $id => $chtoto) {
        $ins[] = $db->parse("(?i,?i,?i,?i)",$id, $chtoto, $array_2[$i],$array_3[$i]);
    }
    $instr = implode(",",$ins);
    $db->query("INSERT INTO `MyTable` (`a`, `b`, `c`, `d`) VALUES ?p", $instr);
    Ответ написан
    2 комментария
  • Использование переменной как списка полей

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Не надо хранить список имён полей в другой таблице.
    Надо прочесть хотя бы букварь по реляционным базам данных и научиться ими пользоваться по-человечески.
    Ответ написан
    7 комментариев
  • Почему исчезают русские символы в MySQL INSERT?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Во-первых, "слишком дорого" - это фантазии.
    Во-вторых, загружая данные в БД, надо ей говорить, в какой они кодировке.
    В-третьих, кодировка тут не при чём. При проблемах с кодировкой текст может либо выглядеть как знаки вопроса, либо как нечитаемые символы. Но не пропадать совсем.

    В общем, не зная никаких вообще деталей, сложно дать конкретные рекомендации, но если предположить, что используется запрос INSERT и mysql_query(), то после соединения с БД надо писать
    mysql_set_charset('кодировка');
    где кодировка - utf8 или cp1251 в зависимости от исходной кодировки файла.

    Для других способов вставки могут понадобиться другие способы указания кодировки.
    Если символы продолжают пропадать - дело не в базе.
    Ответ написан
    Комментировать
  • Как оптимизировать запрос?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Посмотрел на запрос повнимательнее.
    Сдается мне, тут основная проблема в сортировке основной таблицы по неиндексированному полю.
    Предлагаю для начала сделать индекс по полю прайс.
    ALTER TABLE tasks ADD INDEX (status,price);
    причем, поскольку нужна обратная сортировка, а mysql ее в индексах не поддерживает, то цену хранить в отрицательных величинах, а при извлечении брать её по модулю. Пока же для тестов просто убрать DESC из запроса.
    Ответ написан
    8 комментариев
  • Красивые URL и поиск по БД - как вы с этим работаете?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР

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

    Для компьютера и число и строка - это набор байт. Что конкретно в эти байты записано - ему всё равно. Поиск по упорядоченному набору байт будет производиться одинаково.

    Не стоит заранее переживать за производительность. От этого одни проблемы.

    Ответ написан
    Комментировать
  • Оптимизация MySQL UPDATE

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР

    Скорее всего тормоза из-за дефолтных настроек движка InnoDB. Надо либо завернуть все запросы в транзакцию, либо сделать одним запросом, например так:

    
    AND number = IN (....все номера...)
    

    Ответ написан
    Комментировать
  • Какие существуют способы оптимизации часто идуших MySQL запросов на выборку?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Сферический вопрос в вакууме, причём без возможности уточнения, поскольку «проект был».
    «медленные запросы» — насколько медленные?
    «сайт с посещаемостью» — с какой посещаемостью?
    «потому что запросы на поиск» — так может, это поиск вынести отдельно на Сфинкс?

    То есть, выяснить, что там — кривая настройка сервера mysql, кивые таблицы или кривые запросы — не представляется возможным.
    Но вопрос, как всегда, формируется в самом общем виде — «где тот волшебный гвоздь, по которому 1 раз ударить — и всё сразу залетает?»

    Ну ок. В самом общем виде оптимизация запросов (неважно — частых или нечастых) заключается в оптимизации запросов.
    Оптимизированный запрос выполняется (допустим) 0.001 секунды. То есть, БД может обслужить 60 тысяч одновременно сидящих пользователей.

    Берем EXPLAIN и смотрим. Если он говорит, что с запросом все окей, просматриваем ровно столько записей, сколько нужно — 5-10, но все равно запрос исполняется медленно (насколько конкретно медленно — в секундах?) то смотрим, SHOW ENGINE [engine] STATUS. Там уже надо опять же смотреть по месту, решать, чего серверу не хватает.

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

    То есть, действуем как программист — а именно, разбираемся с конкретной проблемой, и ищем решение конкретно для неё.
    А не придумываем от балды заплатку для лечения симптома, оставляя болезнь развиваться и дальше.

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