• Как получить родительскую категорию у подкатегории?

    @Akela_wolf
    Extreme Programmer
    Если у вас неограниченная вложенность, то только через рекурсивный запрос. MySQL 8 научился их делать. Это позволит вам рекурсивно собрать в одном из полей запроса данные из зависимых таблиц. Вот документация

    Вот пример:
    CREATE TABLE cat(
      id INT NOT NULL PRIMARY KEY,
      title VARCHAR(100) NOT NULL,
      parent_id INT NULL
    );
    
    INSERT INTO cat VALUE (1, 'Root1', NULL), (2, 'Root2', NULL), (3, 'Child1', 1),
    (4, 'Child2', 3), (5, 'Child3', 2);
    
    WITH RECURSIVE rcat(id, title, path) AS (
      SELECT cat.id, cat.title, CAST(cat.id AS CHAR(200)) FROM cat WHERE parent_id IS NULL
      UNION ALL
      SELECT cat.id, cat.title, CONCAT(rcat.path, ',', cat.id) FROM cat JOIN rcat ON cat.parent_id=rcat.id
    )
    SELECT * FROM rcat WHERE id=4;


    Пример
    Ответ написан
    7 комментариев
  • Как записать json который содержать массив объектов в pojo?

    @Akela_wolf
    Extreme Programmer
    Скажите, а вас разный регистр буковок в запросе и в ответе (хотя там одни и те же DTO) ни на какие мысли не наталкивает?

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

    @Akela_wolf
    Extreme Programmer
    Открываем документацию и видим:
    Возвращает "true", если модуль установлен, иначе - "false".

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

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

    @Akela_wolf
    Extreme Programmer
    В случае обычной формы браузер не передает информацию о порядке выбора чекбоксов.
    Чтобы сделать так как вы хотите нужно городить на фронте Javascript, который будет отслеживать порядок "щелканья" по чекбоксам и каким-то образом передавать эту информацию серверу. Предположу, что в вашем случае это означает значительную переделку системы.

    Стоит ли данная "свистелка" таких усилий - решать вам.
    Ответ написан
  • Как правильно написать путь до DIV?

    @Akela_wolf
    Extreme Programmer
    Если метод find умеет в CSS selectors то:
    shopProducts = shop.find('#ProductBrowser-1 .div-который-мне-нужен');


    Это явно какая-то библиотека, так как DOM API не имеет метода find. Так что читайте документацию на библиотеку. Если это jQuery - то должно работать, у нее find умеет в селекторы.
    Ответ написан
  • JOIN всегда делает декартово произведение?

    @Akela_wolf
    Extreme Programmer
    Если вас интересует это в плане получаемого результата - то да, можно рассматривать это так: декартово произведение + фильтр строк по условию (и добавление NULL-ов в случае LEFT JOIN).

    Если интересует как это устроено внутри СУБД - то там далеко не всегда будет декартово произведение, потому что это довольно затратная операция. Какие конкретно операции будет выполнять СУБД можно увидеть по EXPLAIN-у - это называется план запроса. Там может быть и NESTED LOOP (вложенный цикл) и MERGE JOIN и другие операции, которые планировщик запроса сочтет подходящими для данного конкретного сочетания таблиц в данном конкретном запросе (на это влияет структура запроса, наличие индексов, собранная по таблицам статистика и пр. факторы, углубляться в которые я сейчас не буду).
    Ответ написан
    Комментировать
  • Есть ли сейчас смысл использования redux-saga, если есть async/await?

    @Akela_wolf
    Extreme Programmer
    Redux-saga является middleware для redux, обеспечивающим асинхронную обработку.
    Если хотите написать аналогичные middleware самостоятельно (учитывая что сам по себе Redux не умеет в асинхронный код и в любом случае какое-то middleware вам потребуется) - никто вам этого запретить не может.

    Вообще правильная архитектура здесь выглядит примерно так, как сделали в MVICore (фреймворк для Котлина):
    (Action + State) -> actor -> (Effect(s) + State) -> reducer -> State
    Первая часть (actor) работает асинхронно и порождает эффекты (может ни одного, может несколько). Вторая часть (reducer) работает синхронно и порождает изменения состояния. Redux обеспечивает только работу reducer, предлагая первую часть реализовывать какими-то middleware, самописными или библиотечными. Так что, наличие в языке async/await эту проблему Redux не решает.
    Ответ написан
  • Как правильно логировать базу данных?

    @Akela_wolf
    Extreme Programmer
    Логировать в БД (в отдельную таблицу) спринг вполне может. Но это, обычно, не очень хорошее решение. В промышленном использовании все-таки лучше логировать в файл, затем logstash -> elastic -> grafana/kibana или аналогичный стек. Можно graylog - решений в общем-то много и смысла нагружать именно реляционную БД логами обычно мало.
    Ответ написан
    1 комментарий
  • Как спроектировать базу для приложения заметочника?

    @Akela_wolf
    Extreme Programmer
    Если вся таблица из БД прилетает в браузер, а затем браузер с этим миллионом разбирается - это неправильно.
    Браузер шлет запрос, типа "дай мне заметки с такими-то тегами, 50 штук", "дай мне заметки за февраль, 3 страница, 50 штук" и т.п. А сервер разбирается и строит запрос в БД. При нормальном АПИ вы сможете менять структуру данных в БД без необходимости переделывать клиент.

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

    Но в целом, для того чтобы пользоваться подобным приложением в личных целях это необязательно.
    Ответ написан
    Комментировать
  • Проблема с объединением нескольких таблиц MySQL?

    @Akela_wolf
    Extreme Programmer
    Во-первых, стрелки на диаграмме принято рисовать в другую сторону - это таблица связи ссылается на таблицу продуктов и на таблицу фотографий.
    Во-вторых, то чего вы хотите, сделать можно но это неправильный путь. Правильных путей тут два:
    1. Построить запрос, который выбирает продукты по определенному условию и присоединяет к ним картинки. В этом случае у вас будет несколько записей на один продукт, отличающихся только картинками (это, я так понимаю, вы сумели сделать). Обрабатывать это не очень удобно, но зато один запрос в БД.
    2. Выбрать сначала продукты, а затем к продуктам выбрать фотографии. Потребуется сопоставить фотографии с продуктами (по ID) на уровне приложения. Зато два запроса в БД и каждый возвращает свой набор требуемых данных.


    Третий правильный путь - использовать ORM, которая возьмет на себя извлечение данных из БД.

    Неправильный (на мой взгляд) путь - использовать агрегирующие функции, как-то так:
    SELECT p.*, JSON_ARRAYAGG(f.filename) AS files FROM product p
    LEFT JOIN product2file p2f ON p2f.product_id=p.id
    LEFT JOIN file f ON p2f.file_id=f.id
    GROUP BY p.id;

    Пример

    Но я считаю этот путь неправильным, потому что: с ростом сложности БД сложность подобных запросов быстро растет и тут начинают вылазить ошибки. А еще потому что вытащить из подчиненной таблицы 2 колонки можно, но порядок элементов в функции JSON_ARRAYAGG не определен, поэтому начинается возня с тем чтобы все это сопоставить. GROUP_CONCAT тоже имеет проблемы (в первую очередь ограничение длины).

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

    @Akela_wolf
    Extreme Programmer
    Дальше учиться на практике. Берете проект, который хотите сделать, например игру. Начните с чего-нибудь простого, тот же классический арканоид или тетрис. Сразу же возникнет уйма вопросов: а как это? А как тут? А как тогда здесь? И через решение этих проблем будете поднимать свой скилл. Для подобных игр не нужно каких-то сложных библиотек (единственная библиотека, которая необходима - это та, которая позволяет рисовать на экране линии, квадратики и кружки). А потенциал для развития - на полгода минимум. Добавление уровней, режимов, бонусов, таблицы рекордов и т.д. Затем, например, изучение на примере этой игры более серьезной графической библиотеки (тот же OpenGL): псевдотрехмерность, текстурирование, освещение и т.д. В конечном итоге может получиться вполне симпатично выглядящая игра и большое количество опыта в разработке реального проекта.

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

    @Akela_wolf
    Extreme Programmer
    Что вы подразумеваете под "вскрыть"? Научиться предсказывать следующее значение? ГПСЧ - в принципе детерминированная функция, предыдущее значение однозначно определяет следующее (рекуррентная функция).

    Если же речь идет об определении коэффициентов a и c, то это делается элементарно: делаете seed=0, следующее значение генератора равно c. Делаете seed = 1 - следующее значение генератора равно (a+c) % m, откуда, при известном m и c вычисляется a.
    Ответ написан
  • Как спроектировать календарь занятий?

    @Akela_wolf
    Extreme Programmer
    Таблица под типы занятий (если она тебе нужна): тренировка, встреча, визит к врачу и т.д.
    Таблица под конкретные занятия - содержит ссылку на тип занятия и конкретную дату и время
    Таблица под расписание повторяющихся занятий - содержит ссылку на тип занятия и расписание (каждый понедельник, каждую третью среду и т.д.)

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

    @Akela_wolf
    Extreme Programmer
    Пробуйте. Вообще запрета брать на работу программистов со средним образованием в законодательстве нет. Так что все на усмотрение конкретного работодателя. Некоторые, разумеется, отсеют вашу кандидатуру на основе формального признака - отсутствие высшего образования. Но кто-то будет смотреть на опыт работы (а он у вас есть). Плюс техническое собеседование. Не скажу что будет легко, но шансы вполне есть. Возможно придется разослать не один десяток резюме, вполне вероятно будут отказы. Но такого что "вообще не возьмут, в принципе не возьмут" я утверждать не стану.
    Ответ написан
    Комментировать
  • Что происходит с током в момент замыкания цепи?

    @Akela_wolf
    Extreme Programmer
    как будто бы часть которая после резисторов должна двигаться быстрее т.к у неё на пути нет препятствий, а часть которая идет через резисторы - идет медленнее. Это верно?

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

    Препятствие на пути электронов (резистор) выражается в том, что на соответствующем участке цепи действует большая разность потенциалов (напряжение). U1, U2, U3 пропорциональны номиналам резисторов (по закону Ома).
    Ответ написан
    3 комментария
  • Можно ли нагружать ноутбук?

    @Akela_wolf
    Extreme Programmer
    Опасаться не надо. Несколько часов - это вообще ни о чем. Если не перегревается - то срок службы сокращается незначительно. Вентилятор на максимальную скорость - чем холоднее железо тем ему лучше, особенно при продолжительной нагрузке. Регулярно чистить от пыли (с какой периодичностью - зависит от количества пыли в месте эксплуатации)
    Ответ написан
    Комментировать
  • Как в результатах запроса колонку превратить в строку?

    @Akela_wolf
    Extreme Programmer
    Если известно количество устройств (и соответственно количество колонок в итоговой таблице) - можно. Пример для 4 устройств:
    CREATE TABLE data(
      device INT NOT NULL,
      date DATETIME NOT NULL,
      metric NUMERIC(10,2) NOT NULL
    );
    
    INSERT INTO data VALUES (1, '2022-01-01 00:00:00', 2.34),
    (2, '2022-01-01 00:00:00', 1.23),
    (3, '2022-01-01 00:00:00', 3.82), 
    (4, '2022-01-01 00:00:00', 0.45),
    (1, '2022-01-01 01:00:00', 2.00),
    (2, '2022-01-01 01:00:00', 1.82),
    (3, '2022-01-01 01:00:00', 3.09);
    
    SELECT date, SUM(d1), SUM(d2), SUM(d3), SUM(d4) FROM (
    SELECT date,
    CASE WHEN device=1 THEN metric ELSE NULL END AS d1,
    CASE WHEN device=2 THEN metric ELSE NULL END AS d2,
    CASE WHEN device=3 THEN metric ELSE NULL END AS d3,
    CASE WHEN device=4 THEN metric ELSE NULL END AS d4
    FROM data
    ) nested
    GROUP BY date;


    https://sqlize.online/sql/mysql80/68e677a2fc577e6c...
    Ответ написан
    2 комментария
  • Как получить значение определенного ключа многомерного массива?

    @Akela_wolf
    Extreme Programmer
    $func = function(array $arr): string {
      return $arr['driver_profile']['id']
    }
    
    $temp = array_map($func, $input['driver_profiles'])
    Ответ написан
    6 комментариев
  • Какой оптимальный алгоритм для однозначного определения слагаемых в сумме?

    @Akela_wolf
    Extreme Programmer
    Самое простое - шифруйте последние 2 цифры номера заказа как копейки в сумме платежа. Или 3 цифры - как последняя цифра рублевой суммы + копейки. Уникальности не будет, но сократить количество кандидатов в 100-1000 раз может оказаться вполне достаточно для вашей задачи.

    Но это такое себе решение. Вообще у наложенного платежа (а бланк наложенного платежа, по идее, готовите вы как отправляющая сторона) есть поле "назначение". И почта обязана вам его отдавать вместе с платежом. Что мешает вписать в назначение номер заказа в вашей системе? "Оплата заказа #XXX-YYY-ZZZZ" или как-то так.
    Ответ написан
    Комментировать
  • Как исправить выведенные ошибки C2109 и C2676?

    @Akela_wolf
    Extreme Programmer
    У вас gosvos имеет тип Gosvo[], а вы пытаетесь использовать его как тип Gosvo* (разыменовывать указатель)
    gosvos[j].name - по идее должно быть так. И сравнение gosvos[j] > gosvos[j+1] тоже не должно работать.
    Ответ написан
    2 комментария