Задать вопрос
Ответы пользователя по тегу MySQL
  • MySQL: как реализаовать поиска по нескольким вхождениям?

    @rPman
    Есть еще instr это однозначно быстрее like

    Ну и fulltext индексы конечно, искать с некоторым языком запросов

    p.s. если искать в строках базы приходится ограниченное количество слов (т.е. грубо говоря список слов определяется проектом, а не свободным вводом от пользователя) то можно заранее (при добавлении строк) построить свой собственный индекс, размещая факт наличия подстроки в строке boolean полем true/false или создав соответствующие таблицы (если наличие слов сильно разряжено - это эффективнее), где наличие записи - факт наличия слова.

    Например у тебя искать нужно три слова: man, woman, child, соответственно создаешь три boolean колонки has_man, has_woman, has_child в той же таблице где анализируемая строка и заполняешь их триггером.

    Или если тот же пример но через таблицы, то в искомой таблице у тебя должно быть primary key поле, и ты создаешь на каждое слово по таблице has_man, has_woman, has_child, с единственным полем id, в эти таблицы помещаешь запись с id из искомой таблицы, если в ее строке есть это слово.. это так же можно делать триггером.
    Ответ написан
    Комментировать
  • Как поставить правильную кодировку в mysql-connector-python?

    @rPman
    Кодировка базы latin не предполагает хранение русских символов, по техническим причинам, соответственно коннектор понятия не имеет как твои символы корректно переводить в utf8.

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

    @rPman
    Используй динамические запросы, напиши с помощью create function свою, в которой с помощью prepare и execute исполняй sql запрос, собираемый из твоей строки в таблицу плюс добавив нужные таблицы, потребность в таблицах нужно будет как то вычислять, анализируя выражение, либо задавать дополнительным полем (рекомендую этот анализ и формирование динамического sql запроса выполнять в тригерах или отдельным вызовом, который ты будешь вызывать после обновления своих формул), вот пример если используются только одна таблица, а логика фильтрации в ней заранее понятна:
    set sql=concat('select ',expr,' into @result from my_table where id=',id)
    prepare stmt from sql;
    execute stmt;
    deallocate prepare stmt;
    set result = @result;
    return result;

    в этом случае expr будет в формате sql а имена переменных из таблицы

    Если таблиц будет несколько, то добавляй имена таблиц, а анализ запроса делай через поиск "имя_таблицы." и делай соответствующий join и фильтрацию по индексам foreign и primary key (не советую делать мега алгоритм, разбирающий всю базу по структурам, хотя если запилишь, будет наверное мощная и полезная система, скорее всего у тебя будет 2-3 запроса, и нужно будет только понять, когда какой использовать)
    Ответ написан
  • Как залить большой файл sql в базу?

    @rPman
    Телепатствую.

    Главная причина, чаще всего, это не отключенные индексы, запись в таблицу с ними это n*log(n), а без индексов это n или даже log(n).

    Раздели sql на место создания структуры и импорт данных. Замени код создания структуры на такой, чтобы таблицы создавались без индексов, и отдельно создание этих индексов уже после (автоматизировать это не сложно, но чтобы так с ходу найти готовый код я не найду).

    Отдельно в sql коде можно расставить commit через некоторое количество (десятки тысяч +-) insert-ов, что бы лог не переполнялся.

    Следующий вариант - оптимизация дисковой записи, найди способ принудительно включить lazy writes на диске с базой, например с помощью виртуализации или хотя бы ext4 опция data writeback. Внимание! в этом режиме любая проблема с ос (например отключили питание) испортит данные. Т.е. на время импорта создай файловую систему для таблиц отдельно, потом данные тупо скопируешь. Но если у тебя норм ssd или дисковый контроллер с хорошим кешем, то это не актуально.

    И если говорить об самым экстремально большом ускорении, размести файлы базы в tmpfs (оперативка, сотня гигабайт сейчас даже дома не проблема)... Можно для этого арендовать в облаке vps-ку, но желательно в этом же датацентре, а то копировать сотню гигабайт может быть долго. И да, следи за тем что бы была та же архитектура процессора и версия mysql
    Ответ написан
    Комментировать
  • Как задать запрос в базу mysql с массивом данных?

    @rPman
    Философия тут простая - ВСЕ данные, которые участвуют в запросе, должны присутствовать в базе данных.

    А это значит, либо данные заливать перед самим запросом во временную таблицу (что имеет смысл делать только при очень большой нужде, например большой объем данных и мало оперативной памяти на бакэнде) либо, все данные уже есть в базе, и выбирать их по идентификатору, добавляя их список в where id in (1,2,3,...)

    Так же есть неплохой по моему мнению (но считается говнокодом) подход - когда данные это сам запрос, что то типа указывая данные для фильтрации по одному
    select ... where name like '%sdf%' union
    select .. where name like '%zxcvx%' union ...
    или подготовив вложенную виртуальную таблицу с данными
    select ... from (
      select 1,2,3 from dual union
      select 5,6,7 from dual union ...
    ) x where ...


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

    Понятно этот подход нужно использовать с умом и не вставлять в любое место бездумно.

    Реляционная база данных - это компромис, когда ты платишь сложностью работы с данными, кучей ограничений и низкой скоростью, за универсальность, легкий многопользовательский доступ и автоматический контроль за целостностью (транзакции), и вот когда этим можно пренебречь, появляется возможность делать так как описал
    Ответ написан
    Комментировать
  • Какую кодировку выбрать для бд чтобы хранить фото?

    @rPman
    бинарные типы данных binary, varbinary или blob потому и бинарные, что к ним не применяются правила символьной трансляции (charset), т.е. к примеру их нельзя сортировать по алфавиту.

    p.s. настоятельно рекомендую трижды подумать, зачем тебе нужно хранить изображения в базе данных, и с высокой вероятностью лучше их хранить в файлах на диске а в базе только имя файла (а можно и имена файлов привести к идентификаторам базы).
    Ответ написан
    Комментировать
  • Как удалить лишнее с БД mysql имея более 7000 id, которые удалять не надо?

    @rPman
    Тебе все ответили, тут два варианта - создавать в базе inmemory таблицу с одной колонкой и без индексов, и на ее основе уже делать
    DELETE FROM A WHERE A.id NOT IN (SELECT id FROM B);


    Либо написать скрипт, который выгрузит все id из базы, сравнит их (пока чисел не миллионы, это вообще не проблема) и сформирует список id которые нужно удалить (если всего 10к то их будет всего 3к), когда на десяток строк в любом языке программирования. Так как удаляются конкретные id то такой запрос будет работать быстрее чем delete where not in и возможно быстрее использования временной таблицы. Особых ограничений на количество id в where id in (...) я не нашел, если они есть то это проблема драйвера подключения к бд.

    Есть еще третий вариант, который потребует изменения всего проекта, но заложит неплохие возможности. В базе данных нужно определить флаг - deleted (boolean), который устанавливать true если запись нужно удалить, это может быть дополнительное поле в каждой таблице где это имеет смысл, либо отдельная таблица (это эффективнее, если удаленные записи долго не нужно хранить) с единственным полем id, куда будут складываться идентификаторы записей на удаление. Естественно все запросы проекта нужно будет модифицировать с учетом этого поля/таблицы, чтобы пропускались записи, помеченные на удаление. Реальное же удаление проводить в момент наименьшей нагрузки на сервер или по другому критерию (например удаленные записи можно хранить для использования, к примеру отчетности). У метода есть подводные камни - например уникальные индексы/ограничения на другие поля нужно так же переделывать на сдвоенные с флагом удаленности, чтобы допускались записи с тем же значением что и удаленные.
    Ответ написан
    1 комментарий
  • Как извлечь топ 15 очков из таблицы чтобы игроки не дублировались?

    @rPman
    так?
    SELECT user_id, name, MAX(points) as max_points
    FROM `games`
    GROUP BY user_id, name
    ORDER BY max_points DESC
    LIMIT 15;
    Ответ написан
    1 комментарий
  • Возможна ли sql инъекция?

    @rPman
    почти наверняка будут глюки при использовании utf8 или любой другой мультибайтовой кодировки, и формировании строки с неправильной комбинацией символов, так как mysql_escape_string не будет их считать опасными (она вообще только для однобайтовых кодировок).

    Чтобы воспользоваться уязвимостью нужно серьезно зарыться в исходники php или mysql и понимать как обрабатываются ими мультибайтовые кодировки.

    Если ты вынужден поддерживать устаревший код, поставь в самом начале кода проверки на входящие параметры, по значению. Почти наверняка можно собрать под используемый язык пользователей простую функцию валидации, а лучше сразу конвертировать в мультибайтовую кодировку и в этот момент проводить все необходимые проверки.
    Ответ написан
    9 комментариев
  • Почему не записываются данные в MySQL базу данных?

    @rPman
    заверши транзакцию в конце скрипта перед close - commit
    p.s. в 2024 году использовать mysqli это моветон.

    использовать видео, да еще и такое зашакаленное и на неадекватном хостинге (как так, по пробелу паузу не делает) чтобы передать исходники это прямое издевательство над теми у кого ты просишь помощи.
    Ответ написан
    9 комментариев
  • Можно ли в mysql хранить 200 колонок, для 10+млн записей?

    @rPman
    Да, для хранения, добавления и чтения данных с анализом этот подход очень хорош, ценой незначительного для твоих объемов (кратного, Rsa97 все расписал) ты получишь огромный прирост производительности. Настоятельно рекомендую протестировать на тестовом стенде на своих данных, особенность хранения null записей в innodb и работа индесов с ними. Что лучше в твоем случае парный индекс в денормализованной форме или 200 индексов в нормальной можно будет определить только тестами (большая таблица может потребовать больше оперативной памяти на индексы).

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

    @rPman
    Left join, оставит записи из левой части, где обычно базовая таблица, а справа подчинённые и справочники (если порядок другой то right join)
    Ответ написан
    Комментировать
  • Правильный бекап базы данных mysql?

    @rPman
    проверять работоспособность бакапов

    p.s. интервал времени между бакапами так же нужно согласовать с веяниями бизнеса, так как это определит, как много информации ты потеряешь при ее восстановлении, и вдруг сутки это слишком больно и нужно делать чаще

    p.p.s. мегаоперативный бакап это репликация (не заменяет обычный так как не защищает например от ошибки пользователя сделавшего delete * from data) с рабочими скриптами превращения резервной ноды в оперативную, тогда смерть базы от аппаратных проблем (например пожар или кража) не остановят бизнес
    Ответ написан
    Комментировать
  • Какой способ хранения и выборки данных предпочтительней?

    @rPman
    Нужно разделять оптимизацию доступа к данным и их хранение.

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

    Один из способов - считать агрегированную информацию в триггере на изменение и добавление данных.

    Поэтому ответ на твой вопрос может стать - первый вариант, но исходные данные хранить в неагрегированном виде в любом случае.
    Ответ написан
    Комментировать
  • Как перенести базу данных из СУБД Postgresql в MySQL?

    @rPman
    Если ты программист, то написать программу в 10 строчек, копирующую содержимое заданной таблицы из одной базы в другую для тебя не должно быть проблемой. Как минимум на php с использованием PDO проблем не возникнет.

    Судя по тому что структуру таблиц ты уже перенес, заморачиваться с этим тебе не понадобится.

    p.s. экспортировать и импортировать данные в своем формате умеют некоторые универсальные GUI для баз данных, например та же WorkBench, там тоже можно сделать экспорт отдельно в виде insert-ов и отдельно структуру.

    p.p.s. ну перенесли вы данные, но данные это самое легкое, запросы тоже переносить нужно, а вот тут совместимость может быть слабая.
    Ответ написан
    Комментировать
  • Производительность решения SQL like vs join?

    @rPman
    Ты забыл третий вариант, самый быстрый и наиболее предпочтительный если общее количество опций не велико (сотни, например у mysql лимит 1024 колонок максимум) - каждая опция это своя колонка, пустое (null) значение будет значить отсутствие опции у записи.

    Недостаток подхода - если у объекта может быть несколько опций с одним именем, то такой подход не работает (но судя по всему это не твой случай).

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

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

    p.s. если говорить про твои варианты:
    * для 1 используй json сериализацию (опция=значение) в mysql для работы с такими данными есть соответствующие методы
    * для 2 постарайся вместо текстовых наименований опций использовать числовые идентификаторы, заведя соответствующий классификатор либо в базе в отдельной таблице либо в виде констант в коде.

    p.p.s. Ну и еще вариант, если тип значений опций - boolean (либо ограничен небольшим количеством значений, например цвет светофора 4 - выключен, красный, желтый, зеленый) то так же заводи для этих значений числовой эквивалент. В этом случае у тебя появляется еще бонус, упаковывать битовые значения (где количество вариантов 2^x и x это количество бит) и хранить в целочисленном поле сразу несколько (правда не все базы позволяют индексировать операции с битами).
    Ответ написан
    3 комментария
  • Как получить массив в массиве, в одном запросе?

    @rPman
    Зачем?

    Я надеюсь ты объединяешь в одном запросе данные изначальной таблицы и той из которой собираешь data с помощью inner (left если нужны записи с пустым data) join?

    Реляционные базы данных это про буквально табличное представление данных, не подразумевающее наличие вложенных списков (в некоторых типа oracle есть такие типы но по сути это как бы отдельный запрос к серверу, да достаточно эффективный но запрос).

    Если тебе нужен плохой совет, ты можешь сериализовать данные, собрав строку из них, например с разделителем ',' с помощью GROUP_CONCAT. В этом случае, используя группировку ты исключишь из результата запроса дубликаты (который умножает данные таблицы на данные data, дублируя колонки из таблицы) но потратишь время на конкатенацию на sql сервере и парсинг (для числ да простой) массива из строки на бакэнде.
    Ответ написан
    6 комментариев
  • Есть ли слово из переменной в списке (разделено запятой) в бд?

    @rPman
    Ты пытаешься список ключевых слов записать как одно значение, это нарушает идеологию работы с реляционными базами, правильно - у тебя должны быть таблица справочник ключевых слов (id,name) и таблица связей м-м (две колонки идентификаторы) между твой целевой таблицы и справочником (каждая запись в ней факт наличия ключевого слова. Соответственно запрос будет на наличие if exists или полсчет количества count или в зависимости от ситуации, проверка наличия связи по конкретному слову через left join и проверки результата на null.

    P.s. если решать именно твоим способом, то у тебя должны быть 4 условия в or, проверки искомого слова слева like "слово,%", справа "%,слово" по середине "%,слово,%" и в единственном варианте ="слово"

    P.s.s. у mysql есть поддержка работы с json сериализацией, храни тогда список слов в json
    Ответ написан
    5 комментариев
  • Каким образом можно снизить нагрузку на MySQL базу данных?

    @rPman
    Загрузить всю или часть таблицы на бакэед, провести работу в памяти и уже на ее основе выполнить необходимые апдейты.

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

    Много мелких запросов это сильно тяжёлая задача для sql баз данных, тем более для слабой машины
    Ответ написан
    Комментировать
  • Сильно ли тяжело для базы данных innoDB 1 500 таблиц?

    @rPman
    Полторы тысячи таблиц для innodb это мало и дополнительной нагрузки это не создаст (помню были какие то заморочки с myisam уже при количестве таблиц больше 100).

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

    Задача не ясна, рекомендации невозможно дать.
    Ответ написан
    1 комментарий