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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    По новым стандартам самое главное - это использовать подготовленные выражения для выполнения запросов. В смысле не подставлять переменные напрямую в запрос, а передавать их отдельно.

    Для mysqli

    Как соединяться
    Как проверить пароль

    Для PDO

    Как видно даже на таких простых примерах, PDO проще и удобнее в использовании, чем mysqli, так что я настоятельно рекомендую PDO
    Ответ написан
    Комментировать
  • Как извлечь одну записи в виде ассоциативного массива в одну строку?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    К сожалению, примеры в мануале были написаны в прошлом веке, не очень сведущими людьми, и с тех пор не менялись. К примеру, оператор if в приведенном коде бессмысленный и вредный.

    Ну и плюс к тому надо же еще немножечко самостоятельно рассуждать. Оператор while нужен только если надо вывести много строк. А если нужна одна, то и оператор while не нужен.

    В итоге весь код с учетом исполнения запроса код можно сократить до трех строк (запихивать всё в одну нет смысла - потом будет неудобно читать)
    $query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,1";
    $result = $mysqli->query($query);
    $row = $result->fetch_assoc();

    Освоившись с объектным синтаксисом, в дальнейшем последние две строчки можно объединять в одну
    $row = $mysqli->query($query)->fetch_assoc();
    Также хочу отметить, что код для соединения с базой данных в примерах также дается ужасный. Более правильный вариант будет такой
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $mysqli = new mysqli("localhost", "my_user", "my_password", "world");
    $mysqli->set_charset("utf8mb4");

    А еще лучше соединяться, как написано здесь, чтобы с одной стороны иметь нормальные сообщения об ошибках, а с другой не вывалить случайно при ошибке все параметры соединения к БД в открытый доступ.
    Ответ написан
    2 комментария
  • Как добавить в конец записи MySQL?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Это неправильно.
    Надо завести отдельную таблицу user_read, в которой будет всего два поля - id пользователя и id новости.
    Соответственно, добавление "в конец" будет обычной операцией вставки.
    Ответ написан
    3 комментария
  • Как вывести количество строк из БД?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Правильный ответ:

    $sql = "SELECT count(*) FROM `users` WHERE `login` = ? OR `email` = ?";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$login,$email]);
    $user = $stmt->fetchColumn();


    Что мы здесь имеем?
    • Во-первых, запрос, защищенный от кривых ручек пользователя похапе, и, как следствие, от неправильного синтаксиса
    • Во-вторых, запрос, защищенный от SQL инъекций.
    Ответ написан
  • Оптимизировать запрос MySQL. Как узнать сколько всего рядов когда использую limit?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Сам по себе еще один запрос - это не лишняя работа, а ерунда на постном масле.
    Вопрос не в том, сколько запросов выполняется, а что именно они делают.

    И в данном случае эти два запроса делают ужас, летящий на крыльях ночи. Я сейчас расскажу, что делает ваш код.
    Сначала этот код просит базу данных отправить в РНР все найденные запросом строки. Все. Без лимита. Чтобы РНР мог посчитать их и потом выбросить.
    После этого код еще раз просит базу отправить, только не все строки, а только часть. И теперь РНР уже не выбрасывает полученные строки, а честно выводит.
    Понятное дело, что смысла в этих замысловатых телодвижениях - ноль целых, ноль десятых.

    Как правильно получить общее количество найденных строк? Надо попросить базу посчитать их

    Ну и разумеется, использование prepare вместе с доморощенной и небезопасной функцией "clearStr" - это вообще за гранью добра и зла. Это примерно как хранить миллион в сейфе, но не запирать его на ключ, а подпирать дощечкой.

    $GLOBALS["mysqlcon"] - это отдельный ужас, но на фоне всего остального меркнет.

    Правильный код будет таким
    $sql = "SELECT count(*) FROM post WHERE MATCH (tags) AGAINST (? IN BOOLEAN MODE)";
    $STH = $GLOBALS["mysqlcon"]->prepare($sql);
    $STH->execute([$_GET['search']]);
    $totalPages=ceil($STH->fetchColumn()/$numPosts); //Узнаем сколько всего страниц существует
    
    $sql = "SELECT * FROM post WHERE MATCH (tags) AGAINST (? IN BOOLEAN MODE) LIMIT ?,?";
    $STH = $GLOBALS["mysqlcon"]->prepare($sql);
    $STH->execute([$_GET['search'],$start, $numPosts]);


    Поскольку все советуют синглтон, вот готовый пример: https://phpdelusions.net/pdo/pdo_wrapper#singleton
    С ним, кроме прочего, код будет короче

    $sql = "SELECT count(*) FROM post WHERE MATCH (tags) AGAINST (? IN BOOLEAN MODE)";
    $numRows = DB::run($sql, [$_GET['search']])->fetchColumn();
    $totalPages=ceil($numRows/$numPosts); //Узнаем сколько всего страниц существует
    
    $sql = "SELECT * FROM post WHERE MATCH (tags) AGAINST (? IN BOOLEAN MODE) LIMIT ?,?";
    $STH = DB::run($sql, [$_GET['search'],$start, $numPosts]);
    Ответ написан
    1 комментарий
  • PHP PDO предопределенная константа PARAM_STR?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    PDO никак не преобразовывает данные. Ни большие, ни маленькие. И предопределенная константа PARAM_STR тут тоже не при чем.
    Ответ написан
    2 комментария
  • PHP PDO почему идет преобразование текста в binary?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Никакого "преобразования" в "binary" при выполнении запроса не происходит.

    В сообщениях об ошибке / логах нестандартные символы кодируются для большей совместимости. К выполненному запросу этот формат не имеет отношения.
    Ответ написан
    3 комментария
  • Как загрузить картинку в папку на php и записать путь в базу mysql?

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

    1. проверять $_FILES['uploadfile']['error']
    2. Проверять расширение файла на соответствие разрешенным по списку
    3. Переименовывать файл, поскольку оригинальные имена - это адище и беспорядок плюс небезопасно.
    Ответ написан
    7 комментариев
  • Как правильно хранить время в бд?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Так и хранить.
    www.mysql.ru/docs/man/TIME.html

    Принятый ответ - это какое-то извращение, которое будет косячить во всех классических случаях - переход на летнее время, високосный год и так далее.
    Ответ написан
    Комментировать
  • Как экранировать строку в REGEXP (mysql) средствами PHP?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Я думаю, что preg_quote() должна подойти.
    Ответ написан
    1 комментарий
  • Можно ли заменять в SQL запросе ' на "?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Эти функции - какой-то ужас, летящий на крыльях ночи. mysql_real_escape_string - вообще за гранью добра и зла.

    Но главное, что я не могу понять - это какое отношение к mysql и mssql имеет функция xss_clean. Ну то есть я даже представить себе не могу, как можно функцию для защиты от xss применять для любых манипуляций c SQL. Это - я не знаю - как положить деньги в презерватив от грабителей. Он же служит для безопасности. Ну вот деньги и будут в безопасности.

    По теме: ради всего святого, используйте PDO с подготовленными выражениями. Это сделает ненужной всю эту мышиную возню с регулярками. PDO поддерживает как mysql, так и mssql, так что разница будет только в синтаксисе запросов, а сам код работы с запросами будет один и тот же

    $sql = "SELECT TOP 10 * FROM user where mssql.department_id=?";  
    $stmt = $conn->prepare($sql);  
    $stmt->execute([$_GET['department_id']]); 
    $users = $stmt->fetchAll();
    
    $sql = "SELECT * FROM user where mysql.department_id=? LIMIT 10";  
    $stmt = $conn->prepare($sql);  
    $stmt->execute([$_GET['department_id']]); 
    $users = $stmt->fetchAll();


    Как можно заметить, в запросах нет ни одной кавычки вообще, что делает сам вопрос про замену бессмысленным.

    От XSS же надо защищаться совсем в другом месте, и также без всего этого ужаса
    Ответ написан
    1 комментарий
  • VARCHAR(255) или VARCHAR(65535), TINYINT или LONGING. Влияют ли на скорость?

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

    На скорость же в SQL влияют совсем другие вещи. В частности - наличие и размер индекса. Вот в отношении индексов как раз надо думать. В частности, по возможности использовать однобайтную кодировку, и ограничивать длину индексируемой части строки.
    Ответ написан
  • Как лучше организовать сущности в Doctrine?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Для столь короткого описания сущности спроектированы верно.

    Какое отношение к этому имеет количество запросов в БД - загадка.
    Ответ написан
    Комментировать
  • Сколько оперативки нужно для mysql при размере таблицы 2гб?

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

    Разумеется, нет. Это вообще никак не связанные вещи.
    В отличие от новомодных словечек типа nosql, реляционные базы данных спроектированы так, чтобы работать с объемами, во много раз превышающими размер оперативной памяти.

    Но чтобы работать нормально, систему надо настраивать. При этом
    изменение схемы таблицы

    Это одна проблема, со своими решениями, а
    тяжелые запросы

    -- СОВСЕМ другая, со совсем другими решениями

    При изменении таблиц в первую очередь важно свободное место на диске.
    А так же производительность дисковой системы вообще. Причем на дешевых (иде) дисках дисковая подсистема грузит именно процессор, а совсем не память

    С "тяжелыми" запросами надо разбираться по отдельности.
    Ответ написан
    2 комментария
  • Какой уровень MySQL/MariaDB нужно знать среднему php-программисту?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Для миддла надо подтянуть только п. 3. У Светы Смирновой есть несколько отличных презентаций по работе с explain, они легко находятся гуглом.

    Еще желательно различать транзакции и блокировки, когда что использовать.

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

    Вообще, по моему опыту, не стоит переоценивать результаты интервью. Когда я 5 лет назад ходил по собеседованиям, то после двух из них, которые я сам посчитал проваленными, мне прислали предложения о работе.
    Ответ написан
    1 комментарий
  • Почему я не могу печатать русские буквы в mysql?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Чтобы сделать запрос с русскими буквами, надо заходить не под рутом, а под нормальной учетной записью.
    Под рутом в консоли будет применяться дефолтная кодировка, а до версии 8.0 это Latin1, в которой русских букв нету.

    При заходе под нормальным юзером консоль mysql автоматически подхватит текущую кодировку клиента командной строки.
    Ответ написан
    Комментировать
  • Почему возникает ошибка 'SQLSTATE[HY000] [2002] No such file or directory'?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Поменять localhost в конфиге на 127.0.0.1

    А лучше поменять "новый хостинг" на нормальный, с пряморукими админами.
    Ответ написан
    Комментировать
  • Как переделать запрос под Prepared Statement?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    сначала пишем волшебную функцию
    function pdo($db, $sql, $params = null) {
            if (!$params)
            {
                 return $db->query($sql);
            }
            $stmt = $db->prepare($sql);
            $stmt->execute($params);
            return $stmt;
    }


    И после этого пишем почти такой же код, как и был
    $md5_hash = md5_file($_FILES["fail"]["tmp_name"], true);
    $res_double = pdo($db, 'SELECT * FROM `download__files` WHERE `md5hash`=?', [$md5_hash])->fetch();
    Ответ написан
    Комментировать
  • Как выбрать родителя и всех детей?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Хотелось бы обьединить всех детей в один элемент.


    Это вопрос не выборки, а обработки результатов.
    База данных не отвечает за формат вывода запрашиваемых данных.

    В PHP с использованием PDO для такого простого запроса можно получить группировку с помощью комбинирования режимов FETCH_GROUP и PDO::FETCH_COLUMN

    Но при большем уровне вложенности или при необходимости получать какие-либо еще данные кроме имени, нужно будет писать обработчик руками.
    Ответ написан
    Комментировать
  • MySQL. В чем разница функций?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Разница очень простая.

    Функция mysqli_real_scape_string не предназначена для защиты против возможных sql-инъекций. И применять ее в таком качестве - прямой путь заполучить инъекцию.
    В то время как одно из назначений функции mysqli_stmt_bind_param - это предотвращение sql-инъекций, поэтому применять её для этой цели можно и нужно.
    Ответ написан
    Комментировать