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

    Поверьте, критерии "правильности" у каждого будут свои.

    Делать ли мне OneToOne связь с другими похожими полями

    Нет. Подумайте, для какой цели вообще существуют связи на уровне БД. Объясните себе, какую задачи они должны решать, что дадут предложенные вами связи?

    Несколько замечаний по текущей структуре:
    1. В целом подобная структура рассчитана на то, что пользователь может быть связан с несколькими записями в отдельных таблицах. Если у вас связь 1-1, логичнее сделать так:
      • в отдельных таблицах убрать id, а в качестве первичного ключа использовать userId, связь по нему остается [предпочтительно];
      • если же вам нужны именно id в отдельных таблицах, то в user наряду с ролью можно хранить id связанной записи (relationId), тогда связь реализовывать уже на уровне приложения, а не БД. Или, на крайний случай, в user хранить recruterId и candidateId [не желательно, но как вариант].

    2. username и fullName - обычно это разные данные: username в паре с password используется для авторизации, а fullName - это ФИО.
    3. Если photoURL и profilePhoto - это одно и то же, зачем дублировать в отдельные таблицы?
    4. Лучше перенести все общие поля в user.
    Ответ написан
    Комментировать
  • #1062 - Дублирующаяся запись '2-6' по ключу 'PRIMARY', как исправить?

    Вы же сами заскринили ошибку.
    Хотите добавить запись с post_id=6, tag_id=2, при этом такая запись в базе уже есть.

    А еще не понятно, зачем в базе у вас кроме составного PrimaryKey есть индексы на каждую колонку. В данном случае они избыточны.
    Ответ написан
  • Поможете с git flow?

    Оба разработчика, когда работают в своих ветках, должны поддерживать актуальное состояние, т.е. периодически вливать (merge) dev в свою ветку.

    Поэтому, прежде чем делать pull request, разработчик B должен вмержить dev в свою ветку. В случае, если при этом возникнут конфликты, он решает их внутри своей ветки. И только после того, как он удостоверится, что эта ветка содержит все коммиты из dev и все тесты проходят, можно делать pull request в dev.
    Ответ написан
    Комментировать
  • Как оптимизировать поиск по сайту?

    Смотрите, в приведенном выше коде вы на каждое нажатие кнопки делаете два действия:
    - запрос на получение json-файла,
    - вычисляете, какие элементы нужно отрисовать в списке.

    1. Предполагаю, что cargo.json не изменяется в момент ввода текста в поисковой строке, верно? А значит нет смысла читать его каждый раз по сети. Т.е. вы можете один раз запросить его содержимое, и затем результат сохранить в памяти (в переменной). Соответственно элементы рендерить, фильтруя этот результат.

    2. Никому никогда не надо искать что-то из 1-2 символов. Поэтому обычно вводят минимальную длину поисковой фразы, начиная с которой производят поиск. К примеру это может быть 3 символа. Т.е. лишь вводя в поле 3 символа и больше, пользователь будет запускать поиск.

    3. Люди набирают текст с разной скоростью. Кому-то, чтобы ввести в поиске слово "товар", нужно 10 секунд, а кто-то справится за 1 секунду... И во втором случае совершенно не нужно 5 раз (на каждый символ) выполнять описанные действия. Поэтому, если между нажатиями проходит "слишком мало времени", предыдущим можно пренебречь. Это т.н. время задержки. Как правило, достаточно 300-500 мс.

    4. Конечно, в интернет-магазинах товары хранятся не в статических файлах (как в примере), а в базах данных. Представляете, если в магазине миллиард товаров, и все будут храниться в огромном json-файле. В вашей реализации нужно будет этот скажем 10Мб файл читать и потом по этому миллиарду строк еще и фильтровать. Поэтому механизм поиска всегда реализуется средствами бекенда. В итоге на конкретный эндпоинт отправляется строка поиска, а в ответе приходят результаты, которые вы рендерите.

    PS. Я намеренно не написал тут ни строчки кода, ведь это учебный проект, а значит вы самостоятельно должны эти моменты (1-3) реализовать. Если что, можете посмотреть исходники готовых решений, они тоже будут реализовывать описанное выше: https://github.com/search?l=JavaScript&q=autocompl...
    Ответ написан
    Комментировать
  • Как составить регулярное выражение?

    Регулярное выражение - это не просто строка.

    Формат (шаблон) у регулярок следующий:
    {delimiter}{regexp}{delimiter}{modifiers}

    В качестве {delimiter} может быть практически любой символ, например / или # или @ и т.п. Обычно выбирается то, что не встретится в самом regexp.
    Про модификаторы тоже почитайте, хоть здесь их нет.

    PHP парсит эту строку, глядя на разделители. Поэтому регулярка должна содержать одинаковые символы разделителя в начале и конце строки (перед модификатором).

    В вашем случае интерпретатор считает, что " - это разделитель, но в конце его не находит. Поэтому и получаете такую ошибку.
    Ответ написан
  • Brackets вкладки открытых документов?

    Насколько я помню, brackets создавался с расчетом на кастомные расширения. Подобная задача как раз решается через установку нужного.
    File / Extension Manager / Available

    И в поиске подбираете по названию.
    5ebfb3405aa60243520571.png
    Например для вашего случая я нашел два:
    https://github.com/DH3ALEJANDRO/custom-work-for-br...
    https://github.com/demonmhon/brackets-working-file-tabs
    Ответ написан
    1 комментарий
  • Как бороться со swap файлами в виме?

    Да, при редактировании файла создаётся соответствующий .swp, где хранятся изменения. И не случайно.

    Например, если вы работаете по сети и пропадает коннект. Несохраненные изменения можно восстановить именно благодаря .swp-файлу: при очередном редактировании vim об этом предупредит.
    Это же даст понять, когда вы пытаетесь редактировать файл, кем-то уже открытый.

    Поэтому бороться с swp-файлами не нужно. Честно говоря, не понимаю проблему. Открываете vim filename.txt, выходите с сохранением :wq, при этом swp-файл удаляется сам.

    https://vi.stackexchange.com/a/179
    Ответ написан
  • Разобраться с АПИ?

    Судя по приведённой в комментариях ссылке, там используется bearer-аутентификация.

    Получив token после авторизации, передавайте его в заголовках запроса в виде:
    Authorization: Bearer awesome-token-12345

    Именно так сервер поймёт, от кого именно идет запрос
    https://swagger.io/docs/specification/authenticati...
    Ответ написан
    Комментировать
  • Как отследить человека?

    Погуглите про GeoIP. Должны быть расширения для любого языка.
    Ответ написан
    Комментировать
  • Как изменить кнопку Яндекс оплаты?

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

    Конструктор позволяет выбрать лишь из нескольких вариантов (4 текста и 3 цвета). Нужно что-то кастомное - создавайте свою форму в соответствии с примерами: https://yandex.ru/dev/money/doc/payment-buttons/re...
    Ответ написан
  • Как запустить скрипт при показе определенного блока?

    Вам незачем высчитывать пиксели. Для подобных задач используют IntersectionObserver. По ссылке и примеры есть.

    Поддерживается практически всеми современными браузерами:
    https://caniuse.com/#feat=intersectionobserver
    Ответ написан
    4 комментария
  • Очень медленный docker?

    Выглядит так, как будто у контейнера просто мало ресурсов. Попробуйте покрутить ползунки в Docker Desktop, если ещё не пробовали: Preferences -> Resources. Сеть он вроде как не режет, а вот memory и cpu да.
    5e7db6afc18c4615357690.png

    У меня такая же конфигурация железа, подобных проблем не замечаю.
    Правда я и не вижу смысла запускать сборки зависимостей и dev-среды внутри контейнера. Обычно используется просто volume (пробрасывается локальный путь). Объясните, зачем вам запускать `npm run dev` внутри контейнера?
    Ответ написан
    4 комментария
  • Как сделать правильную архитектуру платных подписчиков на сайте?

    В БД это дело логично хранить в виде таблиц пользователей и подписок. При подписке создавать запись, где хранить id пользователей (на кого и кто подписался), а также время начала и окончания подписки.

    Пример структуры
    CREATE TABLE `user` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `name` varchar(255) NOT NULL DEFAULT '',
      `type` enum('AUT','SUB') NOT NULL DEFAULT 'SUB',
      PRIMARY KEY (`id`)
    );
    
    CREATE TABLE `subscription` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `author_id` int(11) NOT NULL COMMENT 'На кого подписываются',
      `subscriber_id` int(11) NOT NULL COMMENT 'Кто подписывается',
      `created_at` timestamp NOT NULL COMMENT 'Время подписки',
      `expired_at` timestamp NOT NULL COMMENT 'Когда истекает подписка',
      PRIMARY KEY (`id`)
    );
    
    # Пусть у нас есть один автор и два пользователя:
    INSERT INTO `user` (`id`, `name`, `type`)
    VALUES
    	(1, 'Alex Pushkin', 'AUT'),
    	(2, 'Vasya Pupkin', 'SUB'),
    	(3, 'Jane Doe', 'SUB');
    
    # Один из них подписался на Автора месяцем ранее, второй недавно
    INSERT INTO `subscription` (`author_id`, `subscriber_id`, `created_at`, `expired_at`)
    VALUES
    	(1, 2, '2020-02-15 13:46:12', '2020-03-15 13:46:12'),
    	(1, 3, '2020-03-15 13:46:12', '2020-04-15 13:46:12');


    Если нам надо узнать активные подписки, просто выбираем записи с нужным автором, у которых время подписки подходит.
    SELECT * 
    FROM subscription
    WHERE author_id = 1 and expired_at < CURRENT_TIMESTAMP and created_at < CURRENT_TIMESTAMP;


    Дальнейшую логику, наверное, додумаете сами.

    Можете поиграться в песочнице:
    sqlfiddle.com/#!9/f4fc27/3/0
    Ответ написан
    Комментировать
  • Как оптимизировать слайдер с 50 фотографиям?

    Можете использовать IntersectionObserver.
    Как это работает?
    На нужный dom-элемент навешивается наблюдатеть с колбеком, внутри которого можно делать всё, что угодно. В вашем случае при срабатывании element.isIntersecting это будет загрузка всех стилей/скриптов слайдера и его инициализация.

    Посмотрите пример: https://codepen.io/alnidok/pen/eYNeGMQ

    Поддерживается практически всеми современными браузерами:
    https://caniuse.com/#feat=intersectionobserver
    Ответ написан
    Комментировать
  • Редирект ботов через htaccess?

    Кратко - никак, подробнее ниже.

    Для запрета сканирования краулерами обычно используют robots.txt,
    например такой
    User-agent: Googlebot
    Allow: /
    
    User-agent: Yandex
    Allow: /
    
    User-agent: *
    Disallow: /

    Подробные списки юзерагентов: google и yandex.

    Но robots.txt - это лишь предупреждение, поэтому какие-нибудь SEO-боты попросту его проигнорируют.

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

    Да, есть проекты типа такого, которые обновляют базы определения "плохих ботов". Если это вам и правда надо - изучайте.
    Ответ написан
  • Почему на сайт нельзя зайти по прямой ссылки через гугл?

    Очевидно поэтому: bmox9gbI38nvV2.png
    А уж кто этот код на главную добавлял и зачем, вопрос к вам.
    Ответ написан
    3 комментария
  • Поддерживает ли Яндекс динамически добавляемый json-ld?

    alnidok
    @alnidok Автор вопроса
    Нет. Yandex не поддерживает json-ld в поисковике (только в почте), поэтому нет смысла думать о его динамическом добавлении на страницах сайта.

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

    Да, есть так называемый Keyword Effectiveness Index (KEI) - индекс эффективности ключевого запроса. На его основе можете оценить уровень конкуренции.

    На русском почитайте:
    https://vc.ru/seo/45226-kak-opredelit-konkurentnos...
    https://moytop.com/prodvizhenie-sajtov/formula-kei
    Ответ написан
    2 комментария
  • Почему не добавляются переменные в SQL запрос PHP кода?

    Чтобы понять, в чем проблема, временно добавьте после выполнения запроса var_dump($mysqli->error);
    Скорее всего вы получите ошибку, по которой сразу поймете причину.

    Но есть ряд серьезных ошибок, которые вам нужно исправить и впредь не допускать.
    Подробнее
    • Во-первых, почитайте про sql-инъекции и способы их предотвратить, например подготавливаемые запросы.
    • Во-вторых, в insert-запросе не обязательно перечислять все поля таблицы, чтобы записать в них null. Представляете, если их нам будет 100 колонок? Указывайте только те, в которые реально нужно писать, остальным присвоится значение по-умолчанию на уровне БД.
    Ответ написан
    5 комментариев