• Как синхронизировать две mysql базы?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Если оба MySQL-сервера взаимно доступны, то для решения задачи можно использовать FEDERATED Storage Engine.

    На " другом сервере, где вертится аналитика самописная", перезапускаете MySQL, включив FEDERATED Engine. Далее создаёте подключение (CREATE SERVER), создаёте копию удалённой таблицы на этом сервере - и просто копируете из неё записи за последний месяц. Либо без сервера - прямо при создании таблицы указываете параметры подключения.
    Ответ написан
  • Алгоритм поиска минимального количества ходов, требуемых для приведения всех элементов к одному числу (Python)?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Если количество элементов массива нечётно, то тем значением, к которому надо привести элементы, равно значению строго среднего элемента (медианы массива).

    Если количество элементов массива чётно, то в качестве конечного значения подходит любое значение между двумя средними элементами, включительно.

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Имя учётной записи в MySQL состоит из имени пользователя и хоста пользователя. Оба компонента обязательны и критичны.

    Имя пользователя - задаётся пользователем при подключении. Хост (имя либо адрес) определяется сервером MySQL. самостоятельно, и на этот процесс пользователь почти не имеет возможности повлиять. Объединение этих двух частей и даст полное имя, которое будет использоваться для определения привилегий.

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

    Подробно всё это объясняется в документации в разделе Access Control and Account Management.
    Ответ написан
    Комментировать
  • Как правильно выстроить отношения и спроектировать таблицы?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Нужны ещё как минимум две таблицы.

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

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

    Вместе они задают, какую конкретную роль в конкретной компании имеет конкретный пользователь.
    Ответ написан
    5 комментариев
  • Как вносить в ячейку значение зависимое от даты?

    @Akina
    Сетевой и системный админ, SQL-программист.
    6113d3056202f595026259.png

    Формулы:

    G1=TODAY()-1
    G5:I5=VLOOKUP($G$1;$A$2:$D$11;COLUMN()-5;0)


    То же, если конечная таблица на другом листе:

    6113d3ba2580f247139272.png
    Ответ написан
    Комментировать
  • Postgresql, как получить строки таблицы, попадющие под интервалы записанные в таблице с интервалами?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Полное ощущение, что нужно нечто типа
    SELECT [DISTINCT] t.*
    FROM t
    JOIN t_intervals ti ON t.sequence BETWEEN ti.start AND ti.end
    WHERE ti.id in (2,10,30, ..., n)

    Если интервалы в t_intervals гарантированно не пересекаются (хотя я лично фиг знает как это организовать в виде констрейнтов, а триггерная логика - ниачём), то DISTINCT не требуется.
    Ответ написан
    Комментировать
  • Как вывести последние сообщение?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Если ориентироваться на пример, а не на описание задания, то
    WITH
    cte AS ( SELECT *, 
                    ROW_NUMBER() OVER (PARTITION BY sender, receiver ORDER BY created_at DESC) rn
             FROM message )
    SELECT u1.username sendername,
           u2.username receivername,
           cte.text_message,
           cte.created_at
    FROM cte 
    JOIN users u1 ON cte.sender = u1.id
    JOIN users u2 ON cte.receiver = u2.id
    WHERE cte.rn = 1

    https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=a7a647...
    Ответ написан
    1 комментарий
  • В чем различие 2х запросов?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Основное различие в том, что первый использует картезианское произведение с отбором, что давно уже считается bad practice.

    В остальном именно эти два запроса абсолютно эквивалентны с точностью до порядка выполнения. Операция "запятая" имеет приоритет ниже, чем операция JOIN, т.е. в первом запросе выполняется неявное STRAIGHT_JOIN. И если СУБД не умеет наплевать на это, первый запрос может порождать неоптимальный план выполнения даже при актуальной статистике данных.

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Согласно MySQL 5.7 Reference Manual / ... / Regular Exp...

    [[:<:]], [[:>:]]

    These markers stand for word boundaries.


    Согласно MySQL 8.0 Reference Manual / ... / Regular Exp...

    The Spencer library supports word-beginning and word-end boundary markers ([[:<:]] and [[:>:]] notation). ICU does not. For ICU, you can use \b to match word boundaries; double the backslash because MySQL interprets it as the escape character within strings.


    Так что подход правильный.

    Но Вы не учитываете, что слэш надо квотить как для PHP, так и для MySQL. Т.е. их должно быть не два, а четыре.
    Ответ написан
    Комментировать
  • SQL запрос как создать 9999 записей с итерацией чисел?

    @Akina
    Сетевой и системный админ, SQL-программист.
    1. Вот оно надо, каждый раз заботиться об установлении значений полей DATE_CREATE/DATE_UPDATE?

    ALTER TABLE tablename
    MODIFY COLUMN date_create TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    MODIFY COLUMN date_update TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

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

    2. Для выполнения операции используем рекурсивный CTE (помним, что поля DATE_CREATE/DATE_UPDATE сами заботятся о правильном значении, как и автоинкрементный первичный ключ):

    INSERT INTO tablename (active, user_id, value)
    WITH RECURSIVE
    cte AS ( SELECT 1 num
             UNION ALL
             SELECT num + 1 FROM cte WHERE num < 9999 )
    SELECT 1, 1, num
    FROM cte;


    Возможно, предварительно надо установить достаточное значение для сессионной переменной:SET SESSION cte_max_recursion_depth = 10000;

    Если версия MySQL старая и не понимает CTE, то

    INSERT INTO tablename (active, user_id, value)
    SELECT 1, 1, 1 + t1.num + t2.num * 10 + t3.num * 100 + t4.num * 1000 AS value
    FROM       (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1
    CROSS JOIN (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2
    CROSS JOIN (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3
    CROSS JOIN (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4;
    HAVING value <= 9999;
    Ответ написан
    1 комментарий
  • Как правильно спроектировать связь БД между двумя товарами?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Вопрос: как мне правильно спроектировать таблицу для связей между этими товарами. Чтобы каждый из этих товаров ссылался друг на друга?

    CREATE TABLE groups_of_goods (
        group_id BIGINT UNSIGNED NOT NULL,
        product_id BIGINT UNSIGNED NOT NULL,
        PRIMARY KEY (group_id, product_id),
        FOREIGN KEY fk_product (product_id) REFERENCES product (product_id)
    );


    Соответственно если твои труселя входят в одну группу и ссылаются друг на друга, то в таблице будут 2 записи - (123, 10) и (123, 15).

    Кстати, такая схема обеспечивает и принцип "вассал моего вассала ...". Т.е. "пиджак малиновый" может ссылаться на "брюки малиновые" (через группу 456) и "пиджак в полоску" (через группу 789), но при этом последние два друг на друга ссылаться не будут, ибо разные группы.
    Ответ написан
    2 комментария
  • Какой должен быть тип строки в БД для номера телефона, состоящего из одних цифр?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Насколько я понимаю, надо не только чистить для сохранения и последующего удобного использования, но и возвращать их на место при передаче данных обратно на сайт для отображения или корректировки, верно?

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

    Т.е. если сейчас имеется
    CREATE TABLE users (
        ...
        phone VARCHAR(255),
        ....
    );

    то выполняем
    ALTER TABLE users ALGORITHM = INPLACE
        ADD COLUMN phone_num BIGINT UNSIGNED AS (REGEXP_REPLACE(phone, '[^0-9], ''')) VIRTUAL,
        INDEX idx_phone_num (phone_num);


    Что это даёт?

    Выражение вычисляемого поля чистит строковое значение от всего, что не цифра, после чего значение преобразуется в тип данных поля, т.е. BIGINT UNSIGNED. Отлично, число получено.

    Поле объявлено как VIRTUAL. Это означает, что его значение не хранится в таблице, а вычисляется каждый раз, когда оно потребуется. Но мы создаём по этому полю индекс. Соответственно сервер может не вычислять значение, а извлечь его из индекса. Ещё лучше, если это поле будет включено в композитные индексы вместо поля phone - тогда вероятность, что сервер будет извлекать значение из индекса, увеличится.

    Конечно, можно было бы сделать поле STORED и не морочиться с индексом. Но тогда процесс изменения структуры таблицы будет достаточно длительным, потому что такая операция не может быть INPLACE и требует COPY. Впрочем, это может оказаться более подходящим в определённых условиях.

    Да, следует помнить, что в это поле нельзя записывать значения ни при INSERT, ни при UPDATE - такая операция приведёт к ошибке. Так что про запросы без указания списка полей придётся забыть... ну и SELECT * - тоже забыть.
    Ответ написан
    Комментировать
  • Как правильно сделать Mysql "точный" like запрос?

    @Akina
    Сетевой и системный админ, SQL-программист.
    1. Использовать не LIKE, а функции поиска подстроки (INSTR или LOCATE)
    2. Задать требуемый collation (вплоть до BINARY)
    Ответ написан
    Комментировать
  • Как получить все проекты, у которых нет связи с определенным юзером через 2 таблицу?

    @Akina
    Сетевой и системный админ, SQL-программист.
    я хочу получить все проекты, у которых нет связи с id 4

    SELECT p.*
    FROM project p
    WHERE NOT EXISTS ( SELECT NULL
                       FROM project_user u
                       WHERE p.project_id = u.project_id
                         AND u.user_id = 4 )
    Ответ написан
    Комментировать
  • Можно ли доверять коду ошибки Mysql?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Server Error Message Reference

    Error number: 1452; Symbol: ER_NO_REFERENCED_ROW_2; SQLSTATE: 23000

    Message: Cannot add or update a child row: a foreign key constraint fails (%s)

    InnoDB reports this error when you try to add a row but there is no parent row, and a foreign key constraint fails. Add the parent row first.

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

    Или перед вставкой нужно создать запрос на проверку существования такой записи в связующей таблице?

    А вот задайте себе вопрос - откуда возьмётся то самое значение user_id = 3, которое Вы собираетесь вставить? я не вижу иного способа получить данное значение кроме как сделать запрос в родительскую таблицу. А коли из неё вернётся нужное значение - то запись, из которой взято это значение, совершенно очевидно в таблице есть.
    Ответ написан
    5 комментариев
  • Как лучше реализовать динамические поля?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Принципиально есть два варианта.

    Первый, уже указанный в комментарии от Ерлан Ибраев, EAV.

    Второй - сериализация динамических параметров. JSON, XML и т.п.

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

    Явный недостаток обоих способов - использование унифицированного типа данных в таблице (как минимум строковый, а данные запросто могут потребовать ещё и binary collation) вне зависимости от реального типа сохраняемых данных. Ещё один явный недостаток - необходимость выноса контроля целостности на клиентский уровень.

    Что выбрать? а вот это уже зависит от того, что именно делается с данными.

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT CASE valuta WHEN 1 THEN price
                       WHEN 0 THEN price * 73
                       ELSE NULL 
                       END AS price_in_rub, 
           ...
    FROM ...
    WHERE ...
    Ответ написан
    1 комментарий
  • Как правильно делать JOIN таблиц?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Есть ли разница джоинов этих двух строк, с точки зрения нагрузки на БД?

    Оба запроса - INNER JOIN. Если не используется STRAIGHT_JOIN, то сервер гарантированно построит для обоих запросов один и тот же план выполнения.

    Более того, если Вы почитаете внимательно, как именно сервер выполняет и оптимизирует запросы, то узнаете, что сервер фактически оба этих запроса приводит к картезианскому произведению с отбором. Вернее, препроцессинг выглядит так, словно сервер выполняет такое приведение.
    Ответ написан
    Комментировать
  • Как удалить содержимое БД Mysql?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Самое простое - сделать бэкап только структуры, без данных (mysqldump --no-data, https://dev.mysql.com/doc/refman/8.0/en/mysqldump....), удалить БД, восстановить. Само собой, не забыть забэкапить процедуры/триггеры/прочее.
    Ответ написан
    Комментировать
  • Зачем нужны alias-ы в БД?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Основное назначение алиасов - устранение неоднозначности при наличии одноимённых таблиц/полей.

    Дополнительно - удобство именования, особенно когда оригинальные имена длинные.

    Если ещё смыслы, но они минорны.
    Ответ написан
    Комментировать