Ответы пользователя по тегу MySQL
  • MySql Join как его применить?

    ayazer
    @ayazer
    Sr. Software Engineer
    https://dev.mysql.com/doc/refman/8.0/en/join.html

    SELECT o.address, u.name, u.phone
    FROM `objects` o
    JOIN `users` u on o.userID = u.userID
    WHERE o.userID=12 
    ORDER BY o.created_at 
    OFFSET 1 rows 
    FETCH next 1 rows only
    Ответ написан
    Комментировать
  • Есть ли способ оценить время на изменение схемы?

    ayazer
    @ayazer
    Sr. Software Engineer
    pt-online-schema-change/gh-ost и не страдайте
    Ответ написан
    Комментировать
  • Как быстро изменить схему таблиц?

    ayazer
    @ayazer
    Sr. Software Engineer
    есть 2 проверенных варианта:
    1) github gh-ost.
    2) percona toolkit

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

    percona toolkit - работает через триггеры. потому мигрировать таблицу для которой уже есть триггеры не выйдет. но зато она работает быстрее

    gh-ost - читает бинлог. соотв. будет работать даже если есть триггеры, но работать будет медленно (в моем случае он переливал данные с где-то с такой-же скоростью как они добавлялись)

    в итоге я в свое время использовал для миграций перкону. миграции мелких таблиц в пару гигабайт проходили в течении 10-15 минут незаметно для бекенда.
    Ответ написан
    1 комментарий
  • Регулярное выражение в mysql при update?

    ayazer
    @ayazer
    Sr. Software Engineer
    mysql 8.0 + ? тогда
    UPDATE products SET full_description = REGEXP_REPLACE(full_description, "<h2.+>", "<h2>");


    https://dev.mysql.com/doc/refman/8.0/en/regexp.htm...
    Ответ написан
  • Какие значения задавать типам столбцов?

    ayazer
    @ayazer
    Sr. Software Engineer
    И если всем задам 255, а хранить буду строки 1, то что происходит?

    varchar(255) = 1 * кол-во байт на 1 символ в выбранной кодировке + 1-2 байта технической информации
    сhar(255) = 255 * кол-во байт на 1 символ в выбранной кодировке

    ну и всех прочих равных, индекс по char будет процентов на 15-20 быстрее чем индекс по varchar

    т.е. если у вас по полю будет индекс, и длинна этого поля точно известна (например, четко прописана стандарте с которым вы работаете) - оправдано использовать char. Во всех остальных случаях - проще брать varchar. Экономия char vs varchar на большой таблице вроде действительно может быть гигабайты, но на тех объемах пара гб к размеру таблицы это уже на уровне статистической погрешности при вычислении размера.

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

    ayazer
    @ayazer
    Sr. Software Engineer
    С одной стороны - да, не нормализирована и вообще - классический антипаттерн проектирования, когда в одно поле пихают значения через запятую.

    С другой - надо посмотреть на предметную область и подумать - а дейстительно ли есть есть смысл в разделении? На вид конкретно в данном случае - майскл используется как key-value хранилище, которое быстро достает список документов и отдает его наружу. Дальше сервис уже сделает сплит по запятой и пойдет доставать документы куда-то с хранилища/пойдет куда-то в солр/еластик чтоб уточнить информацию по каждому конкретному документу. Т.е. в случае если нам всегда нужен весь список документов - мы имеем ситуацию когда от разделения мы только теряем (т.к. больше таблиц, больше джойнов, сложнее структура, больше цпу/рам тратится чтоб все достать/хуже кеш хит => мы можем выдержать меньшую нагрузку).

    Нужно четко различать где денормализация т.к. так нужно, а где - т.к. нехватка времени/знаний/желания. И да, этот пример скорее для демонстрации идеи. В реальном мире может оказаться что по ключу "key1" будет лежать строка в пару гигабайт, потому настолько наивный подход работать не будет.
    Ответ написан
    Комментировать
  • Как изменить несколько переменных сразу?

    ayazer
    @ayazer
    Sr. Software Engineer
    ну так обновите метод чтоб обновлять сразу все значения что вам нужны
    UPDATE chats SET {name1}={value1}, {name2}={value2}, ...., {nameN}={valueN} WHERE chat_id = {chat_id}


    https://dev.mysql.com/doc/refman/8.0/en/update.html
    Ответ написан
  • Как сделать выборку из таблицы Mysql по значению в поле кроме цифр?

    ayazer
    @ayazer
    Sr. Software Engineer
    www.sqlfiddle.com/#!9/4d39ea/1/0

    select * from users 
    where value NOT REGEXP "-?^[0-9]*.?[0-9]*$"
    Ответ написан
    Комментировать
  • Как при селекте в mysql выводить нормальную строку?

    ayazer
    @ayazer
    Sr. Software Engineer

    result_vk_user_id = cursor.fetchall()

    Такой селект выводит вот такую ерунду:
    [(323826602,)]


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

    ну и да, нужное вам значение лежит в
    result_vk_user_id[0][0]

    upd:
    ну или можно просто избавится от кортежей и получить список значений
    result_vk_user_ids = [rec[0] for rec in cursor.fetchall()]
    Ответ написан
  • Правильно ли я понимаю, как отработает индекс?

    ayazer
    @ayazer
    Sr. Software Engineer
    нет. главное чтоб в where были или первое поле, или первых два поля, или все 3 поля. в каком порядке вы их напишете в запросе - без разницы.

    т.е. where country = ?? использовать индекс не будет вообще, а where country = ?? and entityId = ?? будет использовать только первую часть составного индекса (по ентитиИд).
    Ответ написан
    4 комментария
  • Как ведет себя JOIN & WHERE?

    ayazer
    @ayazer
    Sr. Software Engineer
    Он выгребет только то что надо. А еще может поменять порядок джойнов чтоб выгребать меньше/быстрее. Но в целом план выполенения запроса будет зависеть от многих факторов (в т.ч. кол-во данных в таблицах, индексы и статистика по этим индексам), потому всегда лучше посмотреть експлейн. А вот нюансы уже могут отличатся от вендора к вендору
    Ответ написан
    2 комментария
  • Как создать триггер не позволяющий добавлять/удалять/изменять при определенных условиях?

    ayazer
    @ayazer
    Sr. Software Engineer
    create trigger <trigger_name> before insert on <table_name>
    for each row
    begin
    if new.val = '' then
    signal sqlstate '45000';
    end if;
    end;$$


    и аналогичные триггеры для before delete/before update

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

    ayazer
    @ayazer
    Sr. Software Engineer
    как все это разбить на конкретные сущности?

    см. ниже

    Какое общее название индексы или ключи?

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

    ForeignKey это тоже индекс/ключ?

    нет, foreign key != индекс. индекс = вообще отдельная структура которая хранится отдельно от самих данных. foreign key = просто ссылка на другую таблицу, и создание внешнего ключа это по сути создание уникального constraint (таблица1.колонка1, таблица2.колонка2). Потенциально СУБД может сама создавать индекс при создании внешнего ключа (т.к. почти всегда это имеет смысл), но это уже нюанс конкретной реализации

    В чем отличие ForeignKey от Reference?


    что такое "Reference"? если вы про конструкцию
    FOREIGN KEY (ColumnName) REFERENCES TableName(ColumnName)

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

    Unique индекс это отдельный индекс или просто флаг unique к обычному индексу?

    это обычный индекс + ограничение на уникальность. и это ограничение в будущем можно как удалить, так и добавить (правда с добавлением не все так просто).
    Ответ написан
    2 комментария
  • Какой порядок порядок полей выбрать при создании индекса MySQL?

    ayazer
    @ayazer
    Sr. Software Engineer

    Так вот, почему сначала в индексе надо сначала указывать age, если можно указать сначала gender и отсечь за одну операцию ~6000 строк (это примерно пол таблицы) и потом в этой половине искать уже по age что будет уже в 2 раза быстрее чем если строить индекс age_gender.


    а если сначала отфильтровать по age - то выйдет СРАЗУ откинуть не половину таблицы, а все кроме тех 200 записей. и потом используя gender - фильтровать не пол таблицы, а только этих 200 записей (а не 6000).

    т.е.
    gender, age -> по первому индексу получаем 6-8к записей, по ним фильтруем используя второй индекс
    age, gender -> по первому индексу получаем 200 записей, по ним фильтруем используя второй индекс (или в случае с low cardinality индексами может оказаться что быстрее просто просмотреть все записи)

    ну и стоить помнить что имея только комплексный индекс (gender, age) поиск по возрасту будет использовать полный перебор. в случае с индексом (age, gender) можно будет и искать по возрасту не указывая пол
    Ответ написан
    3 комментария
  • Ускорение миграции/изменения таблиц в MySQL?

    ayazer
    @ayazer
    Sr. Software Engineer
    1) гитхабовский gh-ost.
    +: работает через бинарный лог, потому может мигрировать таблицу даже если в ней есть триггеры.
    -: работает через бинарный лог, потому (относительно) медленный т.к. в какой-то момент начинает переливать данные где-то с такой-же скоростью как они появляются.

    2) перконовская pt-online-schema-change
    +: работает через триггеры (которые умеют грузить все доступные ядра)
    -: работает через триггеры, потому если триггеры уже есть - использовать перкону не выйдет.

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

    + в новых версиях Mysql можно использовать online ddl для тех-же задач.
    Ответ написан
    1 комментарий