• Система Библитека. Как спроектировать БД для хранения многих экземпляров книг и функционала по заказу этих книг?

    @alexalexes
    В дополнение к сущности "книга":
    Books (id, title, description, year, cover, idAuthor, idGenre)
    Добавить таблицу "экземпляр книги":
    BookEntities (id, -- идент. экземпляра книги
    idBook, -- идентиф. книги
    add_date, -- дата внесения в каталог
    exc_date, -- дата исключения из каталога
    deterioration, -- изношенность
    wieght -- вес
    )
    А в таблицах выдачи/приема уже оперировать экземплярами книг.
    PS: Не всегда в библиотекарской системе требуется такая детализация, может оказаться так, что достаточно отслеживать баланс между макс. кол-во книг, и сколько выдано, при помощи триггеров в базе.
    Ответ написан
    5 комментариев
  • Безопасно ли такая авторизация и последующее открытие страниц?

    @alexalexes
    Эта конструкция небезопасна, если у программиста кривые руки.
    if($rows) {
    $logged = true;
    } else {
    $logged = false; 
    }
    } 
    else {
    $logged = false;
    }

    Статус авторизации очень критичен, и если возникает какая-нибудь ошибка в его проверке, то лучше, чтобы по умолчанию он оставался в значении "не авторизован", то есть false.
    С точки зрения безопасности системы, если произойдет какая-нибудь ошибка, то пользователь лучше не дополучит свой статус, чем случайно получит уровень выше привилегий.
    Поэтому до всяких проверок, инициируете состояние по умолчанию, а потом, выстрадав все проверки присваиваете true.
    // Секция, где присваиваются значения по умолчанию основных переменных
    $logged = false;
    .....
    ....
    // начинаем проверку
    if(первое условие)
    {
      if(второе условие)
      {
        if(еще какое-то супер-пупер условие)
        {
           $logged = true; // вот теперь, пройдя все медные трубы, мы изменяем статус
        }
      }
    }
    Ответ написан
    6 комментариев
  • Почему обьект неправильно поворачиваеться?

    @alexalexes
    Потому, что у вас даны координаты точек в objectc, а не векторные точки от начала координат.
    Чтобы вычислить косинус, а следовательно - угол, нужно брать смещения по X и по Y (deltaX и deltaY) между двумя точками и уже на основе этого смещения вычислять угол.
    var deltaX = objectc[test_prohloe][1] - objectc[key][1];
    var deltaY = objectc[test_prohloe][0] - objectc[key][0];
    var llength = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
    if(llength > 0) // - проверка, что есть различие между точками и есть смысл вычислять новый поворот.
    {
    var cosin =  deltaX / llength; 
    
    console.log(cosin);
    
    var gradus = Math.acos(cosin);
    ctx.rotate(gradus); // rotate square in radians
    }
    Ответ написан
  • Как найти точку пересечения графиков?

    @alexalexes
    Можно. Но реализовать это можно многими путями.
    Вариант А.
    Серверная часть (то бишь PHP) подготавливает как данные, так и графику.
    Это значит, что вы на серверном скрипте как вычисляете все необходимые точки, так и рисуете график, например GD-библиотекой.
    а) Создаете графическое полотно.
    б) Рисуете в этом полотне необходимые линии.
    в) Возможно, где-то что-то подписываете.
    г) Отдаете клиентской части приложения (то бишь браузеру) бинарный поток файла изображения.
    Самый топорный вариант, исследователь графика будет иметь на руках только картинку, ни смаштабировать, и изменить какие-нибудь атрибуты отображения он не сможет. Единственное преимущество - процесс вычисления графика доступен только вашему скрипту, и никто не сможет провести реверсинжиниринг, если захочет разобраться как вы его генерируете.
    Вариант Б.
    На стороне сервера делаете аналитику, отдаете браузеру готовый html-документ, содержащий canvas с генерированными на стороне сервера векторными объектами (линии графика) в svg формате. Это тоже топорный, но уже промежуточный вариант между А и В. Единственное преимущество - все данные векторные, поэтому они будут легковесны для передачи и воспроизведения в браузере.
    Вариант В.
    На стороне сервера делаете аналитику, отдаете данные о вычисленных точках клиенту в виде json, а на клиенте рисуете график в какой-нибудь js-библиотеке. Выбор библиотек широк: chart.js, D3.js и т.д.
    Это самый прогрессивный вариант, поскольку на клиенте можно менять масштаб в окне просмотра графика, менять какие-нибудь атрибуты этого просмотра и т.д.
    Ответ написан
    1 комментарий
  • Стилизация select?

    @alexalexes
    Вместо строчки 42:
    $('select').val(chooseItem).attr('selected', 'selected');

    Используйте:
    $('select option[selected]').removeAttr('selected'); // удаление ранее установленного selected атрибута у одного из option
      $('select option[value="' + chooseItem + '"]').attr('selected', 'selected'); // находим option с нужным value и устанавливаем атрибут selected
    Ответ написан
    Комментировать
  • Какой язык программирования и технологии выбрать для написания программы советника?

    @alexalexes
    Фронтенд составляющая проекта:
    1-3 требования вам выполнит сверстанная на коленке html-форма с элементами логики на JavaScript, даже без vue.
    5 требование - в общем, это любой браузер.
    Бэкенд составляющая проекта:
    4 требование - можно использовать нетребовательные к квалификации разработчика MySQL базу данных и PHP сервер для реализации простейшей логики обращения к этой базе.
    Ответ написан
    1 комментарий
  • Как уменьшить время выполнения запроса?

    @alexalexes
    Делаете отдельную таблицу, в единственном поле и записи которой храните значение этого кол-ва.
    Создаете триггеры для таблицы posts на операции вставки, обновления, удаления.
    В триггере используете этот запрос на подсчет кол-ва и вставку/обновление этого значения в таблице количеств.
    Этим триггером вы переложите 30мс из операции select подсчета кол-ва, на операции insert, update, delete, во время вставки нового значения (обновления категории, статуса, удаления записи), причем в триггере можно игнорировать пересчет, если запись вставляется не того вида (не категория 4 и не статус 1).
    Количество особых записей всегда можно получить моментально из той самой таблицы.
    Ответ написан
  • Как защитить сайт от скачивание файлов?

    @alexalexes
    Запускать игру только в своем окружении.
    Для пользователя написать тонкий клиент в виде видеоплеера с возможностью передавать команды управления интерфейсу приложения.
    На поставщика игры ложится вся ноша генерировать контент в реальном времени - удовольствие не из дешевых.
    На пользователя - иметь широкий интернет канал с малым пингом.
    Цель сохранения авторских прав будет достигнута, но ресурсы будут потрачены о-го-го.
    Ответ написан
    Комментировать
  • Как сделать заголовок "УСЛУГИ" ближе к центру?

    @alexalexes
    Поиграйтесь со стилями селектора, в частности с внутренними отступами:
    .jumbotron {
        padding: 4rem 2rem;
    }

    PS: Не забывайте про медиазапросы с тем же селектором.
    Ответ написан
    Комментировать
  • Как вырезать нужную часть предложения с помощью MySQL?

    @alexalexes
    Можно с помощью функции SUBSTRING_INDEX.
    Два раза применяете эту функцию:
    1. Получаете часть строки "Eau Claire - Home 83", указав разделитель " of ", а номер -1.
    2. Получаете часть строки "Eau Claire", указав разделитель " - ", а номер 1.
    Ответ написан
    2 комментария
  • DELETE FROM list WHERE id = 'id строки в списке дел'. Как мне указать этот id?

    @alexalexes
    1. Подготовить текст запроса prepare-функцией.
    2. Присобачить нужные параметры запроса bind-функцией.
    3. Выполнить запрос execute-функцией.
    Запрос не выполняется? Посмотреть ошибки.
    PS: В любой непонятной ситуации читай документацию.
    Ответ написан
    Комментировать
  • Как реализовать прокрутку текста с помощью табов?

    @alexalexes
    1. Определяете список заголовков.
    2. Определяете offsetTop у каждого заголовка.
    3. Определяете scrollTop у прокручиваемого блока.
    5. Определяете по offsetTop-ам i-ый и i+1 заголовок, где находится значение scrollTop.
    6. Для стрелки вверх делаете scrollTo до i-ого заголовка.
    7. Для стрелки вниз делаете scrollTo до i+1 заголовка.
    8. Если i-ого или i+1 заголовка нет, то гасите кнопку.
    9. На событии скроллинга нужно анализировать пункты 1-8, чтобы кнопки вовремя гасились.
    Ответ написан
    Комментировать
  • Как отзеркалить сопутствующие товары?

    @alexalexes
    Вы этой таблицей кодируете граф (не важно чего).
    Если принимаете за правило, что каждая запись кодирует ребро графа только в одном направлении (граф является направленным), то, чтобы добавить другое направление, тогда вам нужно вставить еще одну запись.
    Например, существует ребро от вершины 1885 до вершины 4683, чтобы прописать ребро с обратным направлением, нужно вставить запись (4683, 1885).
    Список ребер к присоединенным вершинам от данной вершины достаточно выбирать таким запросом:
    select * from t
    where t.idProduct = :id_product and t.relatedProduct <> :id_product -- сравнение с <> исключает петлю на собственной вершине

    Если у вас граф ненаправленный, то можно обойтись одной записью. При получении выборки (ребер графа) вам нужно выбирать не только ребра от вершины idProduct до relatedProduct, но включать те записи, ребра которые прописаны от relatedProduct до idProduct.
    Скорее всего запрос будет иметь такой вид:
    select * from t
    where (    (t.idProduct = :id_product and t.relatedProduct <> :id_product) -- сравнение с <> исключает петлю на собственной вершине
                or (t.relatedProduct = :id_product and t.idProduct <> :id_product))

    Но обязательно нужно определиться, работает ли совместимость товаров в обе стороны, от этого зависит выбор типа графа и правила его чтения/записи.
    Ответ написан
    6 комментариев
  • Можно ли задавать кривые Безье для функций js?

    @alexalexes
    https://easings.net/ru#
    Открываете любой график.
    Внизу приведена формула математической функции.
    Ее используете для создания своего JS аналога.
    Ответ написан
    Комментировать
  • Перенос кириллицы со слешом?

    @alexalexes
    Есть старый добрый тег nobr, который объединяет подстроку, переносимую полностью.
    №<br/><nobr>п/п</nobr>
    Ответ написан
    Комментировать
  • Как во vue js подсунуть добавить переменную в атрибут ссылки href?

    @alexalexes
    Атрибуты тегов конструировать нужно при помощи v-bind (v-bind:href или :href).
    Если внутри кавычек используется объект, то он воспринимается как селектор атрибутов, если строка - то склеивается строка в итоговом значении атрибута.
    <span> Вы получили предложение от пользователя <a v-bind:href="'users/' + item.slug">{{ item.name }}</a></span>
    Ответ написан
    1 комментарий
  • Как объединить GROUP BY и JOIN?

    @alexalexes
    Чтобы найти читателей с последними взятыми книгами, нужно при помощи оконной функции row_number пронумеровать строки в пределах каждого читателя (задав партицию по айди читателя) в порядке убывания по дате taken_at. Из полученного результата взять строки, которые получили номера 1.
    select * from
    (select r.id as reader_id, r.first_name, r.last_name, b.id book_id, b.name, b.pub_date, row_number() over (partition by r.id order by l.taken_at desc) as rownum
    from readers r
    left join log_taking l on r.id = l.reader_id
    left join books b on b.id = l.book_id
    ) a
    where a.rownum = 1

    PS: Связка left join выведет всех читателей, в независимости, брали они книги или нет. Просто join даст список читателей, которые брали книги хоть один раз.
    PPS: Оконные функции доступны с MySQL версии 8.
    Если версия 5, то придется городить велосипед с пользовательскими переменными.
    Ответ написан
    4 комментария
  • Как скопировать данные из 2 таблиц в одну?

    @alexalexes
    Правильно построить выборку из нужных таблиц.
    INSERT into archive (title_product, title_category, price_product) 
    SELECT p.title, c.title, p.price
      from product p
       join category c on p.category_id = c.id
    Ответ написан
    1 комментарий
  • Как найти дни рождения в json наборе?

    @alexalexes
    Лучше детей писать в отдельную таблицу.
    А если очень хочется, то только так колхозить:
    -- MySQL
    select u.user_id, child_bdays.bday
      from user u,
            JSON_TABLE(u.children, '$[*]' COLUMNS (
                    bday VARCHAR(10)  PATH '$'
             )) child_bdays
           where STR_TO_DATE(child_bdays.bday, "%Y-%m-%d") >= DATE(now() - INTERVAL 7 DAY)
             and STR_TO_DATE(child_bdays.bday, "%Y-%m-%d") <= DATE(now() + INTERVAL 7 DAY);
    
    -- MariaDB
    select u.user_id, JSON_EXTRACT(u.children, concat('$[', idx_table.idx, ']')) as bday
      from user u,
         (select 0 idx 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 union select 10 union select 11) idx_table /* впомогательная выборка для генерации индексов в диапазоне 0...11 */
      where idx_table.idx < json_length(u.children) /* отсекаем обращения к несуществующим индексам элементов в JSON*/
        and STR_TO_DATE(JSON_EXTRACT(u.children, concat('$[', idx_table.idx, ']')), "%Y-%m-%d") >= DATE(now() - INTERVAL 7 DAY)
        and STR_TO_DATE(JSON_EXTRACT(u.children, concat('$[', idx_table.idx, ']')), "%Y-%m-%d") <= DATE(now() + INTERVAL 7 DAY)
    Ответ написан