Задать вопрос
Ответы пользователя по тегу MySQL
  • Почему скрипт не понимает, что данные в MySql изменились?

    @rPman
    код, который обновляет данные случайно не начал транзакцию и не завершил ее?
    Ответ написан
  • MySQL + PHP :: Хранение паролей клиентов в базе данных с целью их извлечения, как защить?

    @rPman
    Забудем что принципиально хранить пароли - плохая практика, но так как задача уже такова что хранение вынужденное то:
    1. шифровать логины и пароли (весь набор данных, не имеющих смысл друг без друга, лучше хранить сериализованными в одном поле, особенно когда от задачи к задачи поля меняются, т.е. логин пароль почта api key, gpg ключи шифрования и т.п. пусть это будет свободная json строчка, за ее анализ отвечает клиентская часть приложения)
    2. ключом/паролем, который не хранится в базе данных (он должен являться частью бакэнда, т.е. в том месте где на бакэнде хранятся настройки подключения к внутренним сервисам либо отдельное место хранения) - при разделении работ между людьми (обслуживать базы могут другие люди, чем те кто имеет доступ к бакэнду) чувствительные данные не утекут легко.
    3. логируй все, т.е. показал пароль - сохрани в специальном логе (в базе или файлах уже вопрос организации работ) - кто, когда, с какой машины, что получил
    4. когда показываешь пароль на клиентской машине, повторно запрашивай авторизацию (чтобы не использовалась автосохраненная), важный момент, это исключит кражу данных уже на стороне клиента, очень мало кто правильно организует рабочее место (это просто неудобно и дорого).
    Ответ написан
    2 комментария
  • Как оптимально сделать выборку из БД?

    @rPman
    если нужно по каждой категории - добавь к запросу group by категория, в select будет sum(сумма) и категория

    если выбор критерия вычисляемый, пропиши его формулу в select сумма as field_name ... group by field_name
    Ответ написан
    Комментировать
  • Как увеличить скорость загрузки данных в Mysql?

    @rPman
    Отключить/удалить индексы, вернуть после полного импорта. Это самое большое ускорение.

    Ещё можно изменить стратегию кеширования данных, дело в том что сервер базы данных слишком щепитильно относится к корректности загружаемых данных, выдавая частый fflush, т.е. принудительную запись данных с ожиданием ее окончания. Это актуально для режима работы с базой но первоначальное наполнение пустой базы можно не боятся сбоев, ведь попытку можно перезапустить с нуля. Например можно изменить режим записи в журнал ext4 на data writeback или лучше средствами виртуализации настроить кеширования диска на -device cache=unsafe для qemu.
    Ещё круче можно настроить bcache с кеширующим диском на ramdisk....

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

    @rPman
    Зависимость требований ресурсов от количества записей (участвующих в индексах) - примерно логарифм log(N) или если индексы не используются то N*log(N)

    Про скорость чтения:

    Пока файлы индексов или не иднексируемые данные кешируются в RAM, с увеличением объема данных скорость работы БД будет падать незначительно (время на получение самих данных будет выше чем их поиск), но как только оперативная память закончится (индексы в кеши не влезают) то скорость работы скачкоорбазно упадет.

    Про скорость записи:
    К сожалению на запись данных в базу данных активно используется диск, соответственно зависимость log(N) сохраняется, но будет с большим коэффициентом от скорости диска на запись.

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

    Вот к примеру задача хранения и быстрого доступа к хешам может быть решена быстрее любой БД за счет накладных расходов на дисковое хранилище со скоростями почти равными iops накопителей помноженное на их количество.

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

    @rPman
    Похожесть - перебором.

    У меня в поиске заголовков статей (40к) postgres подсчет левенштейн со всеми записями был меньше секунды, а ведь он фактически перебор делает. Но задача на самом деле сложнее.

    Посмотри хорошую статья с обзором алгоритмов, статья старая но взяв из нее алгоритмы будет что гуглить дальше

    p.s. рандомная ссылка из гугла, в работе есть код на питоне
    Ответ написан
    Комментировать
  • Как безболезненно изменить модель mysql в существующей бд?

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

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

    На практике никто особо не заморачивается, особенно в вебе. Запустил обновление базы, не нарушающее работу старого кода, затем обновил код, и после чистишь базу от старого кода. Даже если в этот момент система будет under maintaince какое то время, не беда...
    Ответ написан
    Комментировать
  • Может ли MySQL глючить?

    @rPman
    Я встречал смутно похожие проблемы (когда буквально where like %zzz% выдавал строки в которых не было 'zzz' когда скорее всего из-за ранее повисшей машины была некорректно перезагружена операционная система и были порушены данные в индексах, repair и пересоздание индекса для гарантии проблему решили.

    Не факт что это твой случае, ты бы хотя бы примеры данных и примеры запроса сюда показал, а то бывает люди надеются на то что порядок в не сортированных данных (или сортировка по не уникальному полю) будет постоянным, а это undefined behavior, именно так это и вылезает в редких неуловимых местах.
    Ответ написан
    Комментировать
  • Стоит ли добавлять index для полей таблицы EAV?

    @rPman
    Если нужны сложные индексы, то в EAV модели появляется дополнительная таблица объектов с выделенными полями под нужные атрибуты, наполняемая тригерами, и уже на них настраиваются индексы.

    Скажи, зачем ты выбрал EAV модель? Зачем создал себе проблем?

    В чем проблема каждому атрибуту создать колонку в таблице, сотни колонок никаких особых проблем (главная рекомендация - не делать default value, если в будущем понадобится удалять добавлять колонки), структура отлично кодом модифицируется и анализируется средствами базы данных, и главное гибко организуются многоуровневые индексы, что сложно реализовать на EAV
    Ответ написан
    6 комментариев
  • Как произвести группировку по последовательным повторам mysql?

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

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

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

    Если будет такое поле (id таблицы или сразу значение твоей второй колонки), то запрос, выдающий что тебе надо будет очень простым и отрабатывать очень быстро
    select date,val from table where val<>prev_val order by id


    p.s. иначе тебе придется на каждое значение искать его предыдущее вложенным запросом через order by limit или max/min limit что не очень быстро
    select date,val from table x where val<>(select val from table y where y.date<x.date order by id desc limit 1)

    спецы могут посоветовать красивее запрос через left join, я считаю нужно избегать таких случаев когда нужно искать соседнюю запись
    вот посмотри как я решал похожую задачу
    Ответ написан
    1 комментарий
  • Как заполнить таблицу в цикле Mysql?

    @rPman
    Дано:
    product_attr_id - растет непрерывно по 1
    attr_7 - растет по 1 через три
    attr_29 - растет по 1 но через 3 записи (или при превышении 1099) возвращается к 1097

    итого:

    делаем один единый цикл по product_attr_id - for ... step 1
    увеличиваем attr_29 на 1 каждый шаг и проверяем выход за границу >1099 присваиваем 1097, так же в этот момент увеличиваем attr_7 на 1
    Ответ написан
    Комментировать
  • Обновлять базу данными, затирая первые старые данные?

    @rPman
    Это худшая задача для реляционных баз данных, что там будет происходить с foreign_key я вообще молчу, все решаемо но скорости будут не очень

    Если нет связанных таблиц (что логично, твой id на самом деле не идентификатор, не вводи народ в заблуждение и назови по другому) в твоем случае скорее всего можно схитрить, можно key_id считать на лету, т.е. ключевое поле с autoincrement, но назови его по другому, например key_id_orig
    1+key_id_orig-min(key_id_orig)

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

    @rPman
    Всегда, если есть возможность сделать два меньших массива вместо одного большого - делай два массива.
    тип - под ситуацию и деньги, raid1 и 0 имеют наименьшие накладные расходы на процессор но кушают доступное место на диске

    raid5 из трех дисков вполне возможен, так как используете десктопные ssd-шники, значит за скоростями не гонитесь и вам хватит софтварного mdadm (настоятельно рекомендую его а не встроенные в zfs и btrfs), поэтому 2 x raid5 по 3 диска - ваш выбор.

    p.s. настрой мониторинг бакапы! а при наличии второй машины, master-slave репликацию для базы, как один из инструментов онлайн резервирования (это так приятно запустить базу данных после сбоя в то же мгновение как умрет главный сервер).
    Ответ написан
    Комментировать
  • Как в mysql выбрать ближайшую бОльшую и ближайшую мЕньшую запись из базы в 1 запрос?

    @rPman
    В комментариях тебе уже ответили вариант с order by. Запрос order by и limit очень тяжелый для sql сервера, его очень сложно оптимизировать.

    Есть еще min max но тебе нужны id, значит вложенный запрос по timestamp, не уверен что это будет быстрее (лучше поэкспериментируй)
    select * from xxx where
       timestamp=(select min(timestamp) from xxx where timestamp > ...)
    or timestamp=(select max(timestamp) from xxx where timestamp < ...)
    p.s. я заметил что ничего не сказано про одинаковые значения timestamp в разных записях, если брать limit 1 то будет выбираться случайная запись (точнее 100500 раз одна но в какой то момент другая - undefined behavior), этот запрос выдаст все записи с одинаковыми timestamp

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

    В каких то ситуациях можно очень СИЛЬНО оптимизировать задачу, если есть какое то знание о том как данные записываются в таблицу. Например если известно гарантированное окно времени, в течении которого поступают данные, и их не сильно много можно просто сделать
    select * from xxx
    where timestamp > date - const_interval
      and timestamp < date + const_interval
    а затем уже среди этих данных выбирать по выше определенным алгоритмам или даже на бакэнде

    Если изменений данных значительно меньше запросов на чтение (особенно если модификации не предполагаются и есть только добавления), то можно складывать искомые значения сразу в момент создания записи (добавлять id новой записи в предыдущую, и тут же ее id в новую), делать это можно как тригерами так и на бакэнде, накладных расходов на такую запись мало зато на чтение данные доступны за константное время, максимально быстро
    select p2.*,p3.* from xxx p1
      left join xxx p2 on p1.id=p2.previous_id
      left join xxx p3 on p1.id=p3.next_id
    where p1.timestamp=...
    в данном случае строчка будет одна, данные раскиданы по колонкам p2.* и p3.*

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

    @rPman
    Да.
    Есть момент, твой объём данных ничтожно мал.

    У хранения данных в базе данных есть два основных подхода - хранить ключ-атрибут-значение, где на атрибут будет отводиться одна строка таблицы, называется eav, и хранение данных в полях, где на один объект отводится одна запись в таблице атрибуты хранятся в колонках.

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

    Второй подход всем хорош и рекомендуется, мало того можно разрабатывать интерфейс приложения с оглядкой на первый способ с возможностью добавления новых атрибутов не как новые записи в базе а как вызов ddl sql модификации таблицу, т.е. добавлять колонки на лету, таким образом получить достоинства eav и скорость аналитики. Недостаток подхода, в общем случае удаление и изменение колонок медленное в базах данных, так как пересоздаётся вся таблица, Но это проблема будет заметна когда объектов сотни тысяч.

    То есть я рекомендую хранить объекты в строках а атрибуты в колонках, даже если их сотни. Старайся отделять разные объекты по разным таблицам.
    Ответ написан
    2 комментария
  • Откуда внезапная нагрузка на сервер?

    @rPman
    Смотри что выполняется в базе show processlist, в идеале профилируй все запросы, смотри какие больше всего времени выполняются, сделать это можно как на стороне приложения (бакэнда), особенно если используется какая то прослойка для базы данных, так и средствами базы данных, гугли mysql slow query log (на самом деле там куча способов проанализировать работу но чаще удобнее это делать со стороны бакэнда)

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

    С некоторой вероятностью - размер базы дошел до некоторого критического, и индексы перестали влезать в оперативную память, но сами запросы к диску все еще кешируются ОС (причем не гостевой а хост системы)

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

    @rPman
    Для запросов, включающих в себя и фильтрацию where и сортировку/групировку, нужны составные индексы (обычно порядок полей в составном индексе рекомендуется сначала поля, которые в условии where, потом те что в group by/order by)

    Опиши модель данных, без конкретики, но важен смысл любых чисел и условий в твоем запросе, в частности меня смущает твое условие first обычно это показывает что что то не так в самом способе хранения и использования данных

    p.s. иногда, когда запросов на чтение сильно больше запросов на запись, логичнее заполнять тригерами искомые данные в кастомной табличке-кеше

    например в твоем случае последняя добавленная запись может быть скопирована на insert/update в дополнительную таблицу (где вообще индексов нет), тогда брать ее от туда будет максимально просто и быстро
    Ответ написан
    Комментировать
  • Почему может тормозить простейший запрос?

    @rPman
    В чем отличия в серверах? количество оперативной памяти? мажорная версия mysql? настройки?
    есть возможность сравнить конфигурации mysql прошлого сервера и нового с помощью SHOW VARIABLES и уже сравнив их на примере каких-нибудь буферов можно что то менять.

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

    Вот посмотри тут как предлагают проверить, влезает ли индекс в память или нет (подправь там условие чтобы твои таблицы были а не все)
    --------------------------------

    Так же предлагаю провести эксперимент, замени SELECT page_id FROM blitz_tasks WHERE stage = 1533 на список значений в константах (1,2,3,4,...), и если это поможет (а должно так как запрос теперь лезет только в одну таблицу и не трогает другие индексы) то будешь дробить свои запросы, избавляясь от вложенностей и нескольких индексов в одном запросе
    Ответ написан
    8 комментариев
  • Как лучше выстроить связи таблиц в бд на основе json файла?

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

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

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

    @rPman
    с помощью if или case switch преврати value_remove/add в знак -/+ перед value, теперь делай sum по получившемуся значению и group by по дням (дату в номер дня преврати, например с помощью day_of_year или бери только день, месяц, год .. как тебе удобно)
    Ответ написан
    Комментировать