<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <language>ru</language>
    <title>MySQL</title>
    <description/>
    <link>https://tproger.ru/tag/mysql</link>
    <atom:link href="https://tproger.ru/tag/mysql/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Thu, 01 Oct 2026 13:59:39 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>MySQL</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Как приручить legacy-код: безопасная модернизация без заморозки фич</title>
      <link>https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki</link>
      <comments>https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[KODE]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki</guid>
      <description><![CDATA[<p>Как модернизировать legacy-код без остановки продукта: Strangler Fig Pattern, feature flags, shadow testing и безопасная миграция данных. Практика и антипаттерны.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki">Как приручить legacy-код: безопасная модернизация без заморозки фич</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Twitter]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[OpenTelemetry]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Legacy]]></category>
      <category><![CDATA[Техника]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 23 Jun 2026 06:16:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Legacy-код — одна из самых болезненных тем в инженерных командах. Обычно все понимают, что система устарела: архитектура мешает быстро выпускать изменения, новые фичи приходится встраивать через обходные пути, тесты либо неполные, либо отсутствуют, а любое изменение в одном модуле неожиданно ломает другой.</p><p>Но при этом к такому коду часто боятся прикасаться. И не без причины. В старых системах редко бывает понятная карта зависимостей. Документация устарела, часть знаний живет только в головах нескольких разработчиков, а бизнес при этом продолжает ждать новых релизов, интеграций и продуктовых экспериментов.</p><p>Так появляется классическая ловушка legacy: систему надо модернизировать, но остановить развитие нельзя. Переписать всё с нуля страшно, поддерживать как есть — всё дороже. В результате продукт обрастает временными решениями, скорость разработки падает, а стоимость каждого следующего изменения растет.</p><p>Хорошая новость в том, что модернизация legacy-кода не обязана быть большим взрывом. Старую систему можно менять постепенно, сохраняя рабочий продукт, не замораживая фичи и не устраивая один критический релиз, от которого зависит всё.</p><h2>Почему Big Bang-переписывание чаще всего заканчивается плохо</h2><p>Когда команда долго живет с устаревшей системой, идея переписать всё с нуля выглядит очень соблазнительно. Кажется, что можно наконец избавиться от технического долга, выбрать нормальную архитектуру, перепроектировать модули, покрыть всё тестами и начать «правильно».</p><p>На старте такой план часто звучит логично. Особенно если текущая система действительно мешает развитию. Например, мобильное приложение растет, у него уже миллионы пользователей, бэкенд написан несколько лет назад как монолит, а каждая новая фича требует изменений в десятке мест. Команда устала чинить регрессии, бизнес устал ждать, и всем хочется «один раз нормально переписать».</p><p>Проблема не в самой идее переписывания, а в условиях, при которых оно проваливается. Большой риск возникает, когда совпадают четыре фактора: переписывание занимает много месяцев, в это время бизнес продолжает развивать старую систему, новая версия покрывает сразу большую часть функциональности, а откат связан с миграцией данных. Если все четыре пункта присутствуют, Big Bang почти гарантированно превратится в долгий и дорогой проект.</p><p>Допустим, команда решила переписать модуль заказов в e-commerce-продукте. В старой версии есть корзина, промокоды, доставка и оплата. Команда планирует за полгода сделать новый сервис заказов. Но за эти полгода бизнес добавляет подписки, подарочные сертификаты, частичную оплату бонусами и новую логику возвратов. В итоге новая система, которую проектировали под старые требования, к моменту релиза уже нуждается в доработке.</p><p>Есть и другая проблема: большой релиз почти всегда несет максимальный риск. Если вы заменяете крупный кусок системы целиком, ошибка влияет сразу на большую часть пользователей. Откат тоже становится сложным, потому что новая логика уже связана с новыми данными, контрактами и интеграциями.</p><p>Big Bang всё-таки бывает оправдан — но в узких условиях. Если кодовая база молодая (год-два), пользователей мало, у системы нет критичного состояния в БД и продукт можно временно заморозить или вести в обоих контурах параллельно, полное переписывание может оказаться дешевле постепенной миграции. Это редкая ситуация, и она быстро исчезает по мере роста продукта. В зрелых системах безопаснее работает другой подход — постепенная архитектурная эволюция.</p><h2>Пример: как команда переписала сервис документов и потеряла полгода</h2><p>Команда сопровождала сервис — старый модуль на aiohttp с Pydantic v1, через который проходила вся обработка путевых листов и актов осмотра транспорта. Сервис существовал шесть лет, был покрыт тестами фрагментарно, а его API использовали мобильное приложение водителей, диспетчерская веб-панель и пакетный импорт.</p><p>Команда решила переписать сервис целиком: перейти на FastAPI, обновить Pydantic до v2, заодно почистить контракты и заменить внутреннее хранилище документов с MongoDB на PostgreSQL. План был рассчитан на четыре месяца.</p><p>Через восемь месяцев проект всё ещё не был готов к выкатке, а к десятому месяцу команда откатила миграцию полностью. Причин было несколько.</p><p>Во-первых, переписывание шло параллельно с продуктовой разработкой. За время миграции бизнес добавил два новых типа документов и изменил правила подписи актов. Новая система проектировалась под старые требования и к моменту готовности уже не соответствовала продукту.</p><p>Во-вторых, команда не написала характеристических тестов. Поведение «как есть» нигде не было зафиксировано, и расхождения находились только в продакшене после переключения.</p><p>В-третьих, у старого сервиса были скрытые побочные эффекты, о которых никто не помнил. При смене статуса документа публиковал событие в Kafka, которое читал биллинг и сервис аналитики. В новой реализации это поведение не было воспроизведено, потому что в коде оно выглядело как «лишний» вызов. После переключения биллинг перестал получать события, и расхождение обнаружили только через две недели — по жалобе финансового отдела.</p><p>В-четвёртых, переключение было сделано «в лоб»: маршрут в API Gateway просто перенаправили на новый сервис. Фича-флага не было, теневого запуска не было, плана отката не было. Когда выяснилось, что новый сервис строже валидирует исторические форматы документов и отклоняет часть старых записей, быстро вернуться на старую реализацию не получилось — её к тому моменту уже отключили на стенде, а в БД успели уйти записи в новом формате.</p><p>В итоге миграцию свернули, потратив около десяти человеко-месяцев и потеряв доверие бизнеса. Сервис до сих пор работает в исходной реализации, а команда переходит к плану, описанному ниже.</p><h2>Strangler Fig Pattern: как заменить систему по частям</h2><p>Один из самых практичных подходов к модернизации legacy-кода — Strangler Fig Pattern. В софтверном виде паттерн был сформулирован Мартином Фаулером в 2004 году под названием StranglerFigApplication. Идея проста: не переписывать систему целиком, а постепенно выносить отдельные части в новую реализацию.</p><p>Название пришло из биологии. Фикус-душитель растет вокруг дерева-хозяина и постепенно вытесняет его. В архитектуре принцип похожий: старая система продолжает работать, новая функциональность появляется рядом, а затем отдельные потоки постепенно переводятся на новую реализацию.</p><p>Представим старый монолит интернет-магазина. Внутри него есть каталог, корзина, заказы, платежи, скидки, личный кабинет и уведомления. Переписать всё сразу — рискованно. Но можно начать с относительно изолированного участка, например с уведомлений.</p><p>Сначала команда описывает текущий контракт: какие события приходят в модуль уведомлений, какие каналы используются, какие шаблоны отправляются, какие ошибки считаются допустимыми. Затем рядом создается новый сервис уведомлений, который реализует тот же контракт. На первом этапе он может даже не отправлять реальные сообщения, а только принимать события и логировать результат. После проверки часть трафика переводится на новую реализацию. Когда сервис стабилизируется, старый код уведомлений удаляется из монолита.</p><p>Strangler Fig хорошо работает там, где между старым и новым кодом есть сетевая граница: HTTP, message bus, RPC. Если такой границы нет — например, нужно постепенно заменить функцию или класс внутри одного процесса — используется родственный паттерн Branch by Abstraction: над старой реализацией создается абстракция, рядом пишется новая реализация, переключение происходит через конфигурацию или фича-флаг, после стабилизации старая ветка удаляется. Снаружи это выглядит как Strangler Fig, но без сетевого прокси.</p><p>Такой подход снижает риск. В системе нет одного большого релиза, где всё меняется сразу. Есть серия небольших контролируемых изменений. Каждое можно протестировать, измерить и откатить.</p><h2>Главное правило: сначала повторить поведение, потом улучшать</h2><p>Одна из частых ошибок при модернизации legacy-кода — попытка одновременно переписать систему и улучшить бизнес-логику. Команда смотрит на старый модуль и думает: «Раз уж мы его трогаем, давайте сразу сделаем нормальную архитектуру, изменим контракты, уберем странные кейсы и перепишем поведение».</p><p>Это опасный путь. В legacy-системах странное поведение часто существует не случайно. За ним может стоять неочевидное бизнес-правило, старый клиент, интеграция с внешней системой или исторический баг, на который уже кто-то завязался.</p><p>Например, в системе расчета налогов может быть правило: для контрактов, заключенных до 2018 года, НДС округляется в меньшую сторону до целого рубля, а для всех остальных — по математическим правилам. Новый разработчик может решить, что это ошибка, и «исправить» округление. Но потом выяснится, что часть крупных клиентов держит это поведение в своих сверках, а смена правила приведет к расхождениям в актах и претензиям.</p><p>Прежде чем менять поведение, его нужно зафиксировать. Для этого пишут характеристические тесты (characterization tests, иногда называемые golden master или approval tests). Идея простая: на реальных данных или их обезличенных копиях прогоняется старая реализация, её ответы сохраняются как эталон, и любые будущие изменения, отклоняющиеся от эталона, отлавливаются автоматически. Тесты пишутся не для красоты, а для того, чтобы зафиксировать существующее поведение — даже странное — перед тем, как его трогать. Подробно эта техника описана у Майкла Физерса в книге Working Effectively with Legacy Code; на практике её удобно реализовать через библиотеки семейства approval-tests (approvaltests-python, approvaltests-java и аналоги).</p><p>Поэтому первый этап модернизации — не улучшение, а воспроизведение текущего поведения. Новая реализация должна вести себя так же, как старая. Даже если старое поведение кажется странным. Только после стабилизации можно отдельно обсуждать, что именно стоит менять.</p><h2>Feature toggles: как включать новую логику без риска</h2><p>Feature toggles, или фича-флаги, — один из главных инструментов безопасной миграции. Они позволяют включать и выключать новую логику без деплоя.</p><p>В обычной разработке релиз часто выглядит бинарно: код либо выкатили, либо нет. При миграции legacy это неудобно. Гораздо безопаснее иметь возможность включить новую реализацию для 1% пользователей, затем для 10%, потом для половины аудитории и только после этого для всех.</p><p>Например, команда переносит расчет стоимости доставки из монолита в новый сервис. С помощью фича-флага это выглядит так:</p><p>user_id передается явно, чтобы решение «попал ли пользователь в новый сегмент» было стабильным от запроса к запросу. Иначе один и тот же клиент будет получать разные ответы при обновлении страницы, и поведение системы станет непредсказуемым.</p><p>На первом этапе флаг включают только для внутренней команды. Потом для тестового сегмента пользователей. Затем для небольшой доли реального трафика. Если метрики стабильны, долю увеличивают. Если появляются ошибки, флаг выключают, и пользователи снова идут в старую реализацию.</p><p>Важно различать два разных типа флагов. Флаг постепенной выкатки (rollout flag) меняется редко и контролирует, какой процент пользователей видит новую логику. Kill switch — отдельный флаг, единственная задача которого — мгновенно выключить новую реализацию при инциденте. Kill switch должен опрашиваться на каждом запросе, его кэширование должно жить секунды, а не минуты, и он принципиально не должен зависеть от той системы, которую он выключает. Иначе в момент аварии может оказаться, что выключатель сам недоступен.</p><p>В качестве инфраструктуры для флагов команды обычно берут одну из платформ: LaunchDarkly, Unleash, Flagsmith, GrowthBook, либо собирают собственную поверх Redis или конфигурационного сервиса. Для миграции важны три свойства: быстрое распространение изменений (секунды, а не минуты), поддержка таргетинга по пользователю/сегменту и аудит — кто и когда менял флаг.</p><p>Важно, что фича-флаг — это не просто if в коде. Для серьезной миграции нужны правила: кто может включать флаг, как быстро его можно отключить, какие метрики отслеживаются, когда флаг должен быть удален.</p><p>Последний пункт особенно важен. Если флаги не удалять, система быстро превращается в набор ветвлений, где никто уже не понимает, какая логика актуальна.</p><h2>Shadow testing: как проверить новую систему на реальном трафике</h2><p>Feature toggles помогают безопасно переключать пользователей. Но перед этим хорошо бы понять, совпадает ли новая логика со старой. Для этого используют shadow testing.</p><p>Shadow testing — это запуск новой реализации параллельно старой, но без влияния на пользователя. Пользовательский запрос по-прежнему обрабатывает старая система, а новая получает копию запроса и считает результат «в тени». Пользователю этот результат не показывается. Команда только сравнивает ответы.</p><p>Например, есть старый модуль расчета скидок. Он учитывает промокоды, сегмент пользователя, историю покупок, регион и партнерские условия. Команда пишет новый сервис скидок. Чтобы не переключать пользователей сразу, можно запустить теневой режим:</p><p>Два момента, на которые стоит обратить внимание в этом коде. Теневой вызов запускается через asyncio.create_task — корутина сразу планируется в event loop и начнёт выполняться, как только функция вернёт управление. И весь блок завернут в try/except: исключение в новой логике не должно ронять основной запрос. Без этих двух свойств shadow testing рискует ухудшить продакшен вместо того, чтобы безопасно его проверить.</p><p>Небольшая оговорка для продакшена: event loop держит на task только слабую ссылку, и без сохранённой ссылки задача может быть собрана сборщиком мусора прямо во время выполнения. В реальном коде Task имеет смысл класть в set фоновых задач и удалять оттуда через add_done_callback. В примере выше эта обвязка опущена для читаемости.</p><p>Для критичной доменной логики — платежей, биллинга, расчета тарифов — допустимый уровень расхождения должен быть около нуля: цель в shadow-режиме не «как можно меньше различий», а «понимаем каждое расхождение». Для менее чувствительных доменов (рекомендации, ранжирование результатов поиска) можно жить с расхождением в долях процента, но и там расхождения нужно классифицировать, а не игнорировать. Возможно, это баги новой реализации. А возможно, старая система содержит устаревшую логику, которую нужно отдельно обсудить с бизнесом.</p><p>Shadow testing особенно полезен для критичных доменных частей: платежей, биллинга, расчета тарифов, персональных предложений, транзакций. Там нельзя просто «попробовать на пользователях» и посмотреть, что будет.</p><p>При этом важно отличать теневую проверку чтения от теневой проверки записи. Чтение проверить относительно дёшево: запрос идёт в обе системы, ответы сравниваются, никаких внешних эффектов нет. С записью всё сложнее. Если новая реализация в shadow-режиме действительно создаст заказ, спишет деньги или отправит письмо, у пользователя возникнут двойные эффекты. Поэтому для writes либо вводят идемпотентные ключи и shadow-режим без реальных побочных действий (внешние вызовы заменены no-op-стабами, БД — отдельной shadow-копией), либо вообще отказываются от теневой проверки записи в пользу постепенной выкатки за фича-флагом.</p><p>Сравнение ответов в реальной системе тоже не сводится к одной функции compare. Нужно отдельно решать, как игнорировать «нормальный» шум (метки времени, идентификаторы, порядок коллекций), как сэмплировать трафик, чтобы не утопить хранилище расхождений, и как организовать триаж — кто и в каком ритме разбирает накопившиеся диффы. Готовые решения этого класса — GitHub Scientist (Ruby и его порты в другие языки), Twitter Diffy, либо собственный лёгкий регистратор поверх Kafka и таблицы расхождений.</p><h2>С чего начинать модернизацию</h2><p>Начинать лучше не с самого больного и не с самого центрального модуля. Это звучит контринтуитивно, потому что обычно хочется сразу взяться за главный источник проблем. Но если начать с ядра системы, команда быстро упрется в максимальное количество зависимостей и рисков.</p><p>Удобный способ выбрать первый кусок — оценить кандидатов по двум осям: насколько модуль критичен для бизнеса (low / high) и насколько сильно он связан с остальной системой (low / high). Начинать стоит с квадранта low-criticality + low-coupling: ошибки в нем не уронят бизнес-показатели, а малое количество зависимостей позволит провести миграцию полностью, не утянув за собой смежные модули. Высоко-критичные и сильно связанные части (платежи, ядро авторизации) трогают в последнюю очередь — на этот момент команда уже наберёт опыт безопасной миграции.</p><p>Хорошие точки входа обычно: уведомления, генерация отчетов, поиск, история операций, профиль пользователя, отдельная часть каталога. Важно, чтобы у команды была возможность описать контракт: какие данные входят, какие выходят, какие ошибки возможны, какие внешние системы участвуют.</p><p>Допустим, в банковском приложении есть старый модуль истории операций. Он медленный, сложно расширяется, но при этом не выполняет сами транзакции. Это хороший кандидат для первой миграции. Ошибка в истории операций неприятна, но обычно менее критична, чем ошибка в списании денег.</p><p>Команда может вынести чтение истории в отдельный сервис, сначала запустить его в shadow-режиме, потом включить для части пользователей, затем полностью перевести чтение на новую реализацию. При этом критичная транзакционная логика останется в старой системе до тех пор, пока команда не наберет опыт безопасной миграции.</p><h2>Миграция данных: самая сложная часть</h2><p>Большая часть статьи говорит о маршрутизации запросов и переключении трафика. Но в реальных проектах основная сложность лежит ниже — в данных. Старая и новая реализации почти всегда работают с общим состоянием: одной БД, одним хранилищем документов, одним набором очередей. Переехать туда «одним коммитом» нельзя.</p><p>Базовый рабочий приём — Expand-Contract (он же Parallel Change). Изменение схемы делается в три такта. На этапе expand в БД добавляются новые поля, таблицы или индексы, при этом старое поведение полностью сохраняется. Затем — migrate: обе реализации начинают писать и в старое, и в новое место (dual writes), а отдельный фоновый процесс делает backfill — заполняет новые поля историческими данными. После этого читатели по одному переключаются на новую схему. Только когда никто из читателей не использует старую структуру, наступает contract — удаление лишних колонок и таблиц.</p><p>Несколько практических деталей, которые часто упускают:</p><p>·         Dual writes — это не бесплатная операция. Две записи означают две точки отказа. Если одна из них упала, нужно решать, что делать: продолжать ли работу, ставить ли событие в очередь на повтор, помечать ли запись как несогласованную. Простое «сначала пишем туда, потом сюда» в продакшене на нагрузке приводит к расхождениям.</p><p>·         Backfill часто длиннее, чем кажется. На большой таблице миграция в одном UPDATE блокирует продакшен. Поэтому backfill делают батчами по N тысяч строк с паузами, отслеживают прогресс и предусматривают возможность остановить и продолжить.</p><p>·         Онлайн-изменения схемы на крупных таблицах делаются не штатным ALTER TABLE, а специализированными инструментами: gh-ost или pt-online-schema-change для MySQL, встроенные онлайн-механизмы PostgreSQL для индексов и колонок, Liquibase/Flyway — для управления версионированием изменений в репозитории.</p><p>·         Shadow testing данные не покрывает. Можно сравнить, что новая реализация возвращает то же, что и старая, но если за этим стоит другая схема в БД, проверка корректности самой миграции данных — это отдельная работа: сверки, контрольные суммы, выборочный аудит исторических записей.</p><p>Без этих шагов любая красивая фасадная архитектура наталкивается на разъезжающиеся данные — и тогда даже идеальный Strangler Fig снаружи не спасает.</p><h2>Прокси-слой как точка контроля</h2><p>Чтобы постепенно заменять legacy-код, нужно управлять маршрутизацией запросов. Для этого часто создают прокси-слой, API Gateway или фасад, через который проходит обращение к старой и новой логике. В терминах Domain-Driven Design такой слой часто называют Anti-Corruption Layer: он защищает новую реализацию от старых контрактов и наоборот, позволяя двум моделям сосуществовать без взаимного «загрязнения».</p><p>Без такой точки контроля миграция становится хаотичной. Часть клиентов ходит напрямую в старый модуль, часть — в новый, часть использует обходные пути, а команда теряет возможность централизованно переключать трафик.</p><p>Прокси-слой решает несколько задач. Он скрывает детали реализации от клиентов, позволяет направлять часть запросов в новую систему, поддерживает фича-флаги, собирает метрики и упрощает откат.</p><p>В качестве технической основы команды обычно берут один из трех вариантов: классический API gateway (Kong, AWS API Gateway), service mesh (Envoy, Istio) или более простой reverse proxy (NGINX, HAProxy). Service mesh особенно удобен, когда трафик уже идёт внутри Kubernetes-кластера: маршрутизацию можно менять конфигурацией, без правок кода клиентов и сервисов.</p><p>Например, мобильное приложение обращается к endpoint /orders/history. Раньше этот endpoint напрямую обслуживал монолит. После введения API Gateway приложение продолжает ходить по тому же контракту, но внутри gateway может решать, куда направить запрос: в legacy-модуль или новый сервис истории заказов.</p><p>Управление маршрутизацией обычно делается не «всё или ничего», а на основании атрибутов запроса: значения заголовка (X-Migration-Cohort: new), куки, хэша от user-id (стабильное разбиение пользователей на сегменты) или географического региона. Это позволяет выкатывать новую реализацию сначала на одну страну, на сотрудников самой компании или на тестовый сегмент — и только потом расширять охват.</p><p>Для клиента ничего не меняется. Для команды появляется управляемость.</p><h2>Наблюдаемость: без метрик миграция превращается в гадание</h2><p>Постепенная модернизация невозможна без нормальной наблюдаемости. Если команда не видит, что происходит внутри системы, она не сможет безопасно переключать трафик.</p><p>Минимальный набор — это логи, метрики и распределенная трассировка (distributed tracing). Нужно понимать, сколько запросов идет в старую и новую реализацию, сколько ошибок возникает, как меняется latency, где появляются таймауты, какие статусы возвращаются, какие бизнес-метрики проседают.</p><p>Технические метрики стоит формулировать не как «средний ответ» и «процент ошибок», а в терминах SLI и SLO: целевые показатели вида «99.9% запросов на /orders/history отвечают быстрее 300 ms за 30 дней» с явным error budget. Latency измеряется по перцентилям (p50, p95, p99) — среднее значение почти всегда обманчиво, а хвосты распределения говорят о реальном опыте пользователя. На время миграции имеет смысл выставить отдельные SLO для нового и старого пути и сравнивать их.</p><p>В качестве инструментов де-факто стандартом стал OpenTelemetry для трассировок, метрик и логов — единый протокол, который пишет в практически любое хранилище. Дальше — Prometheus и Grafana для метрик, Jaeger или Tempo для traces, Sentry или аналог для ошибок. Для миграции важна возможность фильтровать метрики по «варианту» — отдельно по старому и новому пути — иначе все цифры смешаются и реальную динамику будет не видно.</p><p>Технических метрик недостаточно. Если команда переносит оформление заказа, важно смотреть не только на 500 ошибки и время ответа, но и на конверсию в оплату, количество брошенных корзин, повторы запросов, обращения в поддержку.</p><p>Пример: новая система формально отвечает быстрее старой и не дает ошибок. Но после включения на 10% пользователей падает конверсия в оплату. Причина может быть не в серверной ошибке, а в изменении порядка полей, другом тексте сообщения или потере какого-то edge-case. Без бизнес-метрик команда может решить, что миграция успешна, хотя для продукта она уже создает проблему.</p><h2>Практическая последовательность миграции</h2><p>Рабочая последовательность обычно выглядит так.</p><p>Сначала команда выбирает ограниченный участок системы. На этом этапе важно не просто назвать модуль, а описать его границы. Какие сценарии он закрывает? Кто его вызывает? Какие данные он читает и пишет? Какие внешние интеграции использует? Какие неочевидные бизнес-правила в нем есть?</p><p>Затем поверх legacy-логики создается стабильный контракт. Это может быть API, фасад, gateway или отдельный слой внутри приложения. Главная задача — сделать так, чтобы клиенты зависели не от внутренней реализации, а от понятного интерфейса. На этом этапе полезно вспомнить про contract testing (Pact, Spring Cloud Contract): автотесты со стороны потребителей фиксируют, что именно они ожидают от API, и предупреждают о ломающих изменениях до того, как они доедут до продакшена.</p><p>После этого рядом пишется новая реализация. Она должна повторять текущее поведение, а не сразу становиться «идеальной версией будущего». На этом этапе полезно фиксировать все расхождения: где старая система работает странно, где требования не описаны, где бизнес-правила требуют уточнения.</p><p>Следующий этап — shadow testing. Новая система получает копии реальных запросов, считает результат, но пользователю по-прежнему возвращается ответ legacy. Команда сравнивает результаты и устраняет расхождения.</p><p>Когда новая реализация достаточно стабильна, начинается постепенное переключение через feature toggles. Сначала внутренние пользователи, потом 1% реального трафика, затем 5–10%, затем 50% и только после этого 100%.</p><p>На каждом этапе команда смотрит на метрики. Если всё стабильно, движение продолжается. Если появляются проблемы, флаг выключается, трафик возвращается в legacy, а команда разбирает причины.</p><p>Последний этап — удаление старого кода. Это не формальность, а обязательная часть миграции. И «удалить старый код» — это не один коммит, а явный Definition of Done: вырезана старая ветка кода, удалён фича-флаг, обновлена документация и схемы архитектуры, переименованы или удалены устаревшие дашборды и алерты, обновлены runbook’и для on-call и проведено короткое внутреннее обучение. Если этого не сделать, через полгода никто уже не вспомнит, какой путь актуален, и легаси-ветвление останется в коде навсегда.</p><h2>Откат миграций: дешёвый только пока не пошли записи</h2><p>Откатить миграцию, в которой ещё не было записи в БД, легко: достаточно переключить фича-флаг, и трафик снова идёт через старую реализацию. Откатить миграцию, в которой новая система уже неделю писала данные в новые таблицы, — отдельный, гораздо более тяжёлый разговор.</p><p>Поэтому ещё на этапе проектирования каждое изменение должно сопровождаться явным планом отката. Удобно различать три типа шагов.</p><p>Полностью обратимые шаги. Чтение через новый сервис, расчёт «в тени», новые метрики. Откат — выключить флаг. Это самый комфортный режим, и в нём стоит держать миграцию как можно дольше.</p><p>Обратимые с компенсацией. Новая реализация пишет дополнительные данные (например, дублирует операции в новую таблицу), но старый источник тоже обновляется. Откат возможен, но требует решить, что делать с уже записанными данными: оставить, очистить, синхронизировать. План этих действий должен быть написан до выкатки, не во время инцидента.</p><p>Forward-only. После некоторой точки откат становится невозможен — например, после того, как старая схема удалена или внешние интеграции перенастроены на новый сервис. Такие шаги допустимы, но к ним нужно приходить отдельно, осознанно, с особенно строгими SLO в предыдущем этапе. До forward-only-перехода имеет смысл подержать систему в режиме параллельной работы дольше, чем по графику.</p><p>Базовое правило: ни один шаг миграции не должен уходить в продакшен, если у команды нет письменного ответа на вопрос «как мы откатываемся в случае проблемы». Иначе при инциденте откатываться будут на ходу — и не факт, что успешно.</p><h2>Пример: как тот же сервис мигрировали со второй попытки</h2><p>После неудачного опыта команда взялась за тот же сервис заново, но изменила подход.</p><p>На первом шаге они зафиксировали поведение существующего сервиса. На самые часто используемые сценарии (создание путевого листа, подпись акта осмотра, выгрузка пакета документов за период) написали характеристические тесты на реальных продакшен-данных, обезличенных и сохранённых как фикстуры. Любое будущее изменение поведения теперь падало в CI как явное расхождение.</p><p>Параллельно команда провела инвентаризацию побочных эффектов. Из исходного кода и логов выяснилось, что сервис не только хранит документы, но и: публикует событие в Kafka при смене статуса, инкрементирует счётчик в Redis для рейтинга водителей, отправляет webhook во внешнюю систему партнёра, пишет в таблицу аудита. Каждый из этих эффектов попал в отдельный пункт чек-листа «что должно остаться» в новой реализации.</p><p>Затем команда выбрала первый кусок для выноса — не весь сервис, а только чтение документов (GET /documents/{id} и GET /documents/by-driver/{driver_id}). Это была наименее рискованная часть: ошибки в чтении неприятны, но не ломают финансовые потоки.</p><p>Новый сервис написали на FastAPI рядом со старым. На уровне API Gateway появилось правило маршрутизации: запросы на чтение шли в старый сервис, но в фоне дублировались в новый. Ответ пользователю всегда возвращал legacy, а ответ нового сервиса сравнивался с эталоном и записывался в отдельную таблицу для разбора. Использовали обёртку поверх asyncio.create_task — на ответ пользователя теневой вызов не влиял.</p><p>За три недели shadow-режима команда нашла четыре расхождения. Два оказались багами новой реализации (округление времени, неправильная сортировка вложений). Два — давно забытыми особенностями старого сервиса (одно поле возвращалось в UTC, другое — в локальной зоне; так было исторически, бизнес не возражал, но в новой реализации захотели единый формат). Все четыре зафиксировали явно: баги — починили, особенности — согласовали с продуктовой командой как осознанное изменение.</p><p>Когда расхождений не осталось, включили фича-флаг на сотрудников самой компании. Через неделю — на 1% реальных водителей. Дальше шаг по 5%, 25%, 50%, 100% с паузой в несколько дней между этапами. На каждом шаге следили не только за HTTP-ошибками и latency, но и за продуктовыми метриками: количество подписанных актов, время от открытия документа до подписи, доля повторных запросов. Один раз пришлось откатиться с 25% на 5% — в одном из регионов выросло время отклика из-за неэффективного запроса. Исправили, выкатили снова.</p><p>Через два месяца чтение полностью перешло в новый сервис. Старый код чтения и фича-флаг удалили в том же релизе. После этого по той же схеме мигрировали запись документов, потом публикацию событий, потом импорт из внешних систем. Полная миграция заняла девять месяцев — почти столько же, сколько провалившийся Big Bang, — но продукт всё это время продолжал развиваться, инцидентов не было, и в конце команда осталась с системой, которую понимает.</p><h2>Типичные ошибки при работе с legacy</h2><p>Первая ошибка — пытаться улучшить всё сразу. Команда одновременно меняет архитектуру, бизнес-логику, контракты и инфраструктуру. В результате становится невозможно понять, какая именно часть вызвала проблему. Правильнее сначала воспроизвести поведение, стабилизировать новую реализацию и только потом улучшать.</p><p>Вторая ошибка — недооценивать скрытые зависимости и побочные эффекты. Legacy-код часто делает больше, чем кажется. На один и тот же вызов могут быть навешаны: запись в таблицу аудита, инкремент счётчика в кэше, публикация события в очередь, обновление статуса связанной сущности, инвалидация кэша, дёрганье webhook’а во внешнюю систему. Если в новой реализации воспроизвести только явный путь, скрытые потребители молча перестанут получать данные — и узнают об этом через жалобу бизнеса, а не через ошибку в логах. Поэтому перед выносом любого модуля имеет смысл составить инвентаризацию побочных эффектов: пройтись по коду и логам и выписать каждое нелогичное действие отдельным пунктом чек-листа.</p><p>Третья ошибка — отсутствие наблюдаемости. Без логов, метрик и трассировки команда не управляет миграцией, а угадывает. Особенно опасно смотреть только на технические ошибки и игнорировать бизнес-показатели.</p><p>Четвертая ошибка — не договариваться с бизнесом. Модернизация не должна быть невидимой «инженерной активностью в стол». Её нужно встраивать в roadmap, объяснять эффект и договариваться о приоритетах. Если бизнес не понимает, зачем команда тратит время на миграцию, работа будет постоянно проигрывать новым фичам.</p><p>Пятая ошибка — не удалять старый код. Временное сосуществование старой и новой логики нормально. Вечное сосуществование — нет. Если legacy не удаляется, технический долг не уменьшается, а просто меняет форму.</p><p>Шестая ошибка — не удалять фича-флаги после миграции. Флаг, который сыграл свою роль и больше никогда не выключается, превращается в постоянное ветвление в коде. Через год команда не помнит, можно ли удалить такую ветку или там сидит важный edge-case. Через два — кода с такими «мёртвыми» флагами становится больше, чем основной логики. Поэтому каждый флаг должен заводиться с условием удаления («после полной выкатки и двух недель стабильной работы») и иметь ответственного, кто этим удалением займётся.</p><p>Отдельно стоит упомянуть организационную сторону. Закон Конвея работает и в обратную сторону: если новый и старый код владеются разными командами с разными приоритетами, миграция будет тормозиться независимо от выбранного паттерна. На время миграции имеет смысл явно проговорить, кто отвечает за переход, и не разделять старую и новую реализации между несовместимыми roadmap’ами.</p><h2>Компромиссы, к которым нужно быть готовыми</h2><p>Постепенная модернизация безопаснее Big Bang-переписывания, но она не бесплатна. Некоторое время система будет сложнее, чем раньше. В ней появятся старый и новый код, прокси-слой, фича-флаги, дублирование логики, дополнительные метрики.</p><p>Shadow testing увеличит нагрузку на инфраструктуру, потому что часть запросов будет обрабатываться дважды. Команде придется поддерживать дисциплину: документировать контракты, отслеживать флаги, удалять старую реализацию после миграции, поддерживать contract-тесты в актуальном состоянии.</p><p>Но это контролируемая сложность. Она распределена во времени и управляется инженерными практиками. В отличие от Big Bang-риска, где команда долго работает с минимальной обратной связью, а потом выкатывает один большой релиз с максимальной неопределенностью.</p><h2>Когда Strangler Fig особенно оправдан</h2><p>Постепенная миграция особенно хорошо подходит для систем, где downtime невозможен или слишком дорог. Это финтех, e-commerce, биллинг, мобильные бэкенды с большой аудиторией, высоконагруженные продукты, старые монолиты и системы с большим количеством интеграций.</p><p>Если продуктом ежедневно пользуются сотни тысяч или миллионы людей, нельзя позволить себе «переписать и посмотреть, что будет». Нужно менять архитектуру так, чтобы пользователь не замечал процесса миграции.</p><p>Этот подход также полезен там, где бизнес продолжает активно развивать продукт. Если фичи нельзя заморозить на полгода, модернизация должна идти параллельно с продуктовой разработкой.</p><h2>Когда модернизацию лучше не делать</h2><p>Постепенная миграция — мощный инструмент, но у неё тоже есть стоимость, и иногда правильный ответ — оставить систему как есть. Несколько сценариев, в которых модернизация плохо окупается.</p><p>Продукт, который уходит из эксплуатации. Если через год сервис будет выключен или заменён на покупное решение, тратить квартал на его рефакторинг бессмысленно. Достаточно стабилизировать то, что есть.</p><p>Модуль, который никто не трогает. Если код десятилетней давности продолжает работать, не падает, не требует изменений и не вызывает инцидентов, его «уродливость» — не повод его переписывать. Цель модернизации — упростить будущие изменения; если будущих изменений нет, цели тоже нет.</p><p>Регулируемые системы с тяжёлой ресертификацией. В банковских, медицинских и государственных контурах любое изменение в критичной системе может потребовать повторной сертификации, перепрохождения аудитов, обновления договорной обвязки. В таких условиях стоимость модернизации может на порядок превышать стоимость поддержки текущей реализации, и решение нужно принимать вместе с владельцем продукта и юристами, а не только инженерным составом.</p><p>Простой тест: если на вопрос «какой бизнес-сценарий мы откроем после миграции» нет внятного ответа — модернизацию имеет смысл отложить и заняться чем-то другим.</p><h2>Что получает команда</h2><p>Главный результат постепенной модернизации — управляемость. Команда начинает лучше понимать систему, контролировать изменения и снижать риск инцидентов.</p><p>Появляются понятные контракты, наблюдаемость, практика безопасных релизов, культура удаления старого кода. Разработчики перестают бояться legacy, потому что у них появляется метод, а не только желание «когда-нибудь всё переписать».</p><p>Для бизнеса это тоже выгодно. Продукт продолжает развиваться, сроки становятся более прогнозируемыми, риски крупных сбоев снижаются, а технический долг постепенно уменьшается.</p><h2>Модернизация — это процесс, а не проект</h2><p>Legacy нельзя «починить за квартал». Если система развивалась годами, она не станет простой после одного рефакторинга. Но её можно системно улучшать.</p><p>Strangler Fig Pattern, Branch by Abstraction, feature toggles, shadow testing и аккуратная миграция данных дают рабочую модель: выбрать ограниченный участок, описать контракт, реализовать новую версию, проверить её на реальном трафике, постепенно переключить пользователей и удалить старый код.</p><p>Это не самый быстрый путь. Зато он управляемый. А в зрелых продуктах управляемость важнее скорости.</p><p>Потому что цель модернизации — не написать красивую новую систему. Цель — сделать так, чтобы продукт продолжал развиваться, команда могла безопасно вносить изменения, а пользователи не становились участниками инженерного эксперимента.</p>]]></content:encoded>
    </item>
    <item>
      <title>Семь ошибок индексации БД, которые убивают производительность SaaS на корню</title>
      <link>https://tproger.ru/articles/sem-owibok-indeksacii-bd-kotorye-ubivayut-proizvoditelnost-sa</link>
      <comments>https://tproger.ru/articles/sem-owibok-indeksacii-bd-kotorye-ubivayut-proizvoditelnost-sa?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sem-owibok-indeksacii-bd-kotorye-ubivayut-proizvoditelnost-sa</guid>
      <description><![CDATA[<p>Разбираем 7 типичных ошибок индексации в PostgreSQL и MySQL: переиндексация, низкая селективность, раздутие индексов, мультитенантность и внешние ключи. Проверьте свою БД перед релизом.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sem-owibok-indeksacii-bd-kotorye-ubivayut-proizvoditelnost-sa">Семь ошибок индексации БД, которые убивают производительность SaaS на корню</a>»</p>]]></description>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[Масштабируемость и ограничения памяти]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 03 Jun 2026 05:30:09 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ваш код чист, архитектура продумана, а запросы на staging укладываются в 12 мс. Но при 500 000 записей всё встаёт: панели мониторинга тормозят, пользователи жалуются, а дежурный инженер в полночь разглядывает план выполнения запроса и не понимает, что пошло не так. В девяти случаях из десяти причина — не отсутствие индексов, а <b>неправильные индексы</b>.</p><p><b>Индекс в базе данных</b> — это вспомогательная структура (чаще всего B-дерево; хеш-индексы, GiST, GIN и другие типы применяются в узких специфических сценариях), которая ускоряет выборку строк по заданным колонкам. По аналогии с оглавлением книги: вместо перелистывания всех страниц СУБД сразу переходит к нужной главе. Но если оглавление построено плохо, пользы от него нет — а вот накладные расходы на поддержку остаются.</p><p>В этой статье разберём семь самых разрушительных ошибок индексации в production-SaaS: от параноидального создания индексов «на всякий случай» до игнорирования раздутия и особенностей мультитенантных схем. Каждая ошибка — с примерами SQL, метриками и конкретным фиксом.</p><p>Индексы — это налог на запись: каждый INSERT, UPDATE и DELETE обновляет все индексы таблицы.</p><p>Индекс на колонке с низкой селективностью (boolean, статус) почти бесполезен — используйте частичные (partial) индексы.</p><p>В составном индексе порядок колонок критичен: PostgreSQL может использовать (a, b, c) только если условие начинается с a.</p><p>Раздутые индексы на высокоизменяемых таблицах могут занимать в 8 раз больше места, чем нужно — планируйте REINDEX CONCURRENTLY.</p><p>В мультитенантных системах индекс по tenant_id один часто недостаточен: добавляйте диапазон времени или тип события.</p><p>Внешние ключи в PostgreSQL не индексируются автоматически — после каждого FOREIGN KEY создавайте индекс вручную.</p><p>Без EXPLAIN ANALYZE индексы создаются вслепую. Проверяйте реальный план выполнения перед деплоем.</p><h2>Ошибка 1. Индексировать всё подряд «на всякий случай»</h2><p>Самая распространённая ошибка — не недостаток индексов, а их избыток из тревожности. Особенно часто в неё попадают junior-разработчики: добавляют индекс на каждую колонку, которая встречается в WHERE, «на всякий случай». Кажется ответственным, но на самом деле вредно.</p><p>Каждый индекс — это налог на запись. При INSERT, UPDATE и DELETE PostgreSQL (или MySQL) вынуждена обновлять <b>все</b> индексы таблицы. На таблице с 8 индексами каждая запись трогает 8 структур данных. При низкой нагрузке это невидимо, но при 10 000 записей в минуту это становится узким местом.</p><p><b>Аудит неиспользуемых индексов в PostgreSQL:</b><br />Запрос к pg_stat_user_indexes покажет, сколько раз каждый индекс применялся с момента сброса статистики. Если idx_scan = 0 — индекс кандидат на удаление.</p><p>Не удаляйте индекс сразу — сначала убедитесь, что он не нужен для редких, но критичных отчётов. Но если он месяцами не используется, смело избавляйтесь.</p><h2>Ошибка 2. Не понимать селективность</h2><p>Индекс на булеву колонку — почти всегда бесполезен. <b>Селективность</b> измеряет, сколько различных значений содержится относительно общего числа строк. У boolean всего два значения. Если 95% строк имеют is_active = true, планировщик запросов проигнорирует индекс и сделает Seq Scan — и будет прав.</p><p>Правило большого пальца: если у колонки меньше 10–20 уникальных значений относительно размера таблицы, простой индекс по ней один не справится. Используйте частичные или составные индексы.</p><h2>Ошибка 3. Неверный порядок колонок в составном индексе</h2><p>Составные индексы мощны, но часто неправильно понимаются. PostgreSQL может использовать индекс (a, b, c) для фильтрации по a, a и b, a, b и c. Но <b>не может</b> эффективно использовать его, если запрос фильтрует только по b или c — ведущая колонка пропущена.</p><p>Решение: первыми ставьте колонки с equality-условиями, затем — по селективности, и проектируйте индексы вокруг <b>реальных паттернов запросов</b>, а не вокруг схемы таблицы. Также учитывайте ORDER BY и необходимость покрывающего индекса. Перед созданием обязательно запускайте EXPLAIN ANALYZE.</p><h2>Ошибка 4. Игнорировать раздутие индексов</h2><p>Индексы деградируют со временем. Многие инженеры воспринимают их как «поставил и забыл», но это заблуждение. В PostgreSQL при обновлении или удалении строки старые записи в индексе устаревают и накапливаются как <b>раздутие</b> (bloat); их физическое удаление происходит при выполнении VACUUM. На высокоизменяемых таблицах (заказы, события, логи, сессии) раздутие накапливается стремительно.</p><p>Таблица с 1 млн живых строк может иметь индекс, раздутый до размеров 8 млн записей. Каждый запрос через такой индекс делает в 8 раз больше работы, чем должен.</p><p><b>REINDEX CONCURRENTLY</b> — ключевое слово. Обычный REINDEX блокирует таблицу, а в production-SaaS это прямой путь к инциденту. CONCURRENTLY перестраивает индекс без блокировок, хотя и медленнее.</p><p>Также убедитесь, что autovacuum настроен под вашу реальную нагрузку на запись. Значения по умолчанию в PostgreSQL консервативны и часто недостаточны для SaaS с высокой интенсивностью записи.</p><h2>Ошибка 5. Индексы на колонках с малым числом уникальных значений в мультитенантных системах</h2><p>В мультитенантной архитектуре почти каждый запрос фильтрует по tenant_id. Естественное желание — проиндексировать эту колонку. Но для крупных тенантов индекс по tenant_id вернёт слишком много строк, и планировщик предпочтёт Seq Scan. Для маленьких тенантов отдельный индекс по tenant_id может быть полезен.</p><p>На серьёзном масштабе правильное решение — партиционирование таблиц по tenant_id, но это архитектурное решение. Практический первый шаг — составные индексы с временными диапазонами.</p><h2>Ошибка 6. Не индексировать внешние ключи</h2><p>В PostgreSQL внешние ключи <b>не индексируются автоматически</b>. При удалении родительской строки СУБД должна проверить все дочерние таблицы на наличие ссылающихся записей — и без индекса на внешнем ключе это Seq Scan по каждой дочерней таблице. На таблице orders с 50 млн строк удаление пользователя вызывает полное сканирование.</p><p>Сделайте это командным соглашением: в чек-листе миграций обязательный пункт «после каждого FOREIGN KEY — CREATE INDEX».</p><h2>Ошибка 7. Не использовать EXPLAIN ANALYZE перед деплоем</h2><p>Большинство решений об индексах принимаются интуитивно. Интуиция ошибается достаточно часто, чтобы это стало проблемой. EXPLAIN ANALYZE показывает, что именно делает планировщик: какие индексы использует, какие игнорирует, сколько строк реально прочитал против оценки, где тратится время.</p><p>На что обращать внимание:<br />• <b>Seq Scan</b> на большой таблице при выборке малой доли строк — возможно, пропущен индекс или планировщик не может использовать существующий индекс.<br />• <b>Rows Removed by Filter</b> в десятки тысяч — индекс есть, но неправильные колонки или низкая селективность.<br />• <b>Buffers: shared hit=0 read=45000</b> — данные не закэшированы (cold cache), страницы читаются с диска. Для диагностики раздутия смотрите общее число буферов и сравнивайте размер индекса с ожидаемым.<br />• Высокое <b>actual time</b> — проверьте раздутие, актуальность статистики, количество буферов, дисковую подсистему и наличие блокировок. Запустите ANALYZE tablename, чтобы обновить статистику планировщика.</p><h2>Чек-лист индексации для SaaS</h2><ul><li>У каждой колонки внешнего ключа есть индекс?</li><li>Составные индексы упорядочены по селективности, а не по удобству?</li><li>Булевы и низкокардинальные фильтры используют частичные индексы вместо полных?</li><li>Вы запускали EXPLAIN ANALYZE на 10 самых медленных запросов за неделю?</li><li>Есть процесс поиска и удаления неиспользуемых индексов?</li><li>Высокоизменяемые таблицы регулярно проходят REINDEX CONCURRENTLY?</li><li>Autovacuum настроен под реальный объём записи, а не под значения по умолчанию PostgreSQL?</li><li>В мультитенантных таблицах индексы начинаются с tenant_id и включают диапазон времени?</li></ul><h2>Выводы</h2><p>Индексы — не фича производительности, которую добавляют, когда всё начинает тормозить. Это проектное решение, которое принимается вместе со схемой, и пересматривается по мере эволюции паттернов запросов. Команды, которые уверенно масштабируются, — не те, у кого больше всего индексов, а те, кто понимает, что каждый индекс стоит, что даёт и когда его пора убирать.</p><blockquote>База данных, которая быстра на 10 000 строках и быстра на 50 миллионах, — не случайность. Это результат того, что кто-то считал планирование запросов первоклассной инженерной задачей, а не рутинным дополнением.</blockquote><p>Проверьте свои самые медленные запросы этой недели — возможно, одна из этих семи ошибок уже сидит в вашей production-базе.</p><p><b>Источник и материалы:</b><br />• <a href="https://dev.to/outworktech/database-indexing-mistakes-that-kill-saas-performance-at-scale-4j8e">Database Indexing Mistakes That Kill SaaS Performance at Scale</a> — оригинальная статья OutworkTech<br />• <a href="https://www.postgresql.org/docs/current/indexes.html">PostgreSQL Index Types</a> — официальная документация<br />• <a href="https://www.postgresql.org/docs/current/sql-reindex.html">REINDEX</a> — документация по перестроению индексов</p>]]></content:encoded>
    </item>
    <item>
      <title>OwnCloud – аналог Nextcloud: для чего использовать и как настроить облачное хранилище</title>
      <link>https://tproger.ru/articles/owncloud-analog-nextcloud-dlya-chego-ispolzovat-i-kak-nastroi</link>
      <comments>https://tproger.ru/articles/owncloud-analog-nextcloud-dlya-chego-ispolzovat-i-kak-nastroi?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Oksana Karelina]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/owncloud-analog-nextcloud-dlya-chego-ispolzovat-i-kak-nastroi</guid>
      <description><![CDATA[<p>ownCloud vs Nextcloud, что лучше? Какое облачное хранилище выбрать? Как может помочь связка S3 с ownCloud?
</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/owncloud-analog-nextcloud-dlya-chego-ispolzovat-i-kak-nastroi">OwnCloud – аналог Nextcloud: для чего использовать и как настроить облачное хранилище</a>»</p>]]></description>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Конференции]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[macOS]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Персональные данные]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 07 May 2026 08:40:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Вы когда-нибудь задумывались, сколько информации производит человечество?</p><p>Если верить статистике, сейчас ежедневно создается около <a href="https://explodingtopics.com/blog/data-generated-per-day">402,74</a> миллионов терабайт данных.</p><p>Согласитесь, довольно внушительная цифра.</p><p>В этих реалиях, когда объем данных постоянно растет, у каждого из нас рано или поздно может возникнуть вопрос – где хранить рабочие и личные файлы, да еще и так, чтобы сохранить абсолютный контроль над ними.</p><p>Меня зовут Оксана, я маркетолог в Beget и в этой статье хочу поделиться решением, которое мы выбрали у себя в отделе для хранения файлов, когда заметили, что их стало слишком много.</p><p>Мы решили перейти на гибкое объектное хранилище S3 – чтобы централизовано хранить и управлять текстами, креативами, отчетами и другими маркетинговыми материалами с удобным доступом внутри команды, ведь S3 позволяет хранить файлы любого типа и объема и масштабируется автоматически. Осталось только выбрать ПО для хранения файлов в облаке, к которому можно подключить S3.</p><p>Ранее у нас был опыт использования Nextcloud, однако его функционал, подобный швейцарскому ножу (встроенные календарь, конференции, таск-трекер и т. д.), оказался слишком объемен для нашей, по сути, скромной задачи – удобного и стабильного хранения файлов.</p><p>Вот почему мы подыскали аналог Nextcloud – ownCloud. В отличие от более функционального <a href="https://beget.com/ru/cloud/marketplace/nextcloud">Nextcloud</a>, ownCloud заточен исключительно на работу с файлами. И при этом он поддерживает подключение облачного объектного хранилища S3. Поэтому для нас в сравнении Nextcloud vs ownCloud выбор был очевиден.</p><p>В этой статье я расскажу, какие возможности есть у ownCloud, почему это ПО может быть полезно и как настроить связку ownCloud и S3. Если вы хотите организовать безопасное, контролируемое хранение и обмен данными на работе или дома, то этот материал будет для вас полезен.</p><h2>Что может ownCloud</h2><p>Для начала – буквально несколько слов об ownCloud и его возможностях.</p><p>Это программное обеспечение с открытым исходным кодом для хранения, синхронизации и обмена файлами появилось в 2010 году благодаря усилиям разработчика KDE Франка Карличека, который <a href="https://ru.wikipedia.org/wiki/OwnCloud">стремился</a> создать бесплатную альтернативу коммерческим облачным сервисам хранения данных.</p><h3>OwnCloud позволяет:</h3><ol><li>получать доступ к данным из любой точки мира и хранить файлы на собственном сервере – под вашим полным контролем;</li><li>синхронизировать данные между устройствами – доступ к файлам возможен с компьютеров (Windows, macOS, Linux), смартфонов (iOS, Android) и через браузер, изменения на одном устройстве мгновенно появляются на всех остальных;</li><li>делиться файлами и папками по ссылке, настраивая права доступа, пароли и срок действия ссылок;</li><li>совместно работать с документами, отслеживать историю изменений и возвращаться к любой предыдущей версии файла.</li></ol><blockquote>Только ownCloud сочетает в себе полный контроль над данными с простыми в использовании функциями обмена файлами, делая совместную работу более эффективной и безопасной.</blockquote><p>Сегодня ownCloud используют <a href="https://owncloud.com/customers/">компании</a> (Philips, Nationwide, Zeppelin и др.) в самых разных сферах (IT, машиностроение, медицина и т. д.).</p><p>При этом решение подходит не только для работы, но и для личных целей, когда нужно обменяться фото и видео с родственниками и друзьями, ведь, по мнению пользователей, среди преимуществ ownCloud – <a href="https://www.capterra.com/p/176602/ownCloud/reviews/">простота настройки</a> и <a href="https://www.temjournal.com/content/102/TEMJournalMay2021_954_960.pdf">удобная синхронизация с различными гаджетами</a>.</p><blockquote>С ownCloud мне не нужно слепо доверять какой-то неопределенной организации. Я контролирую, как происходит обмен файлами, и ownCloud помогает мне на каждом этапе.</blockquote><p>OwnCloud позволяет решать самые разные задачи, связанные с работой с файлами, – расскажем на примере трех кейсов, как это облачное хранилище помогает нам в отделе маркетинга.</p><h2>Для каких задач мы используем ownCloud и S3</h2><h3>1. Централизованное управление материалами</h3><p>Мы часто работаем с текстами, изображениями и презентациями. Дизайнеры и авторы загружают эти материалы в ownCloud, файлы автоматически сохраняются в S3, а для удобства поиска у нас настроены теги.</p><p>В итоге каждый член команды может видеть версии файлов (это важно для правок), нет хаоса в почте и мессенджерах.</p><h3>2. Безопасное взаимодействие с подрядчиками</h3><p>Связка ownCloud и S3 позволяет выгружать внешним специалистам материалы и получать результаты работ без прямого доступа к внутренней сети компании. Мы создали папку с публичной ссылкой, но жесткими ограничениями – паролем, сроком жизни ссылки в течение нескольких дней и разрешением на загрузку файлов без права просмотра папки.</p><p>На практике это работает так: менеджер создает ссылку и отправляет подрядчику, подрядчик переходит по ссылке и загружает архив с готовыми материалами, файл попадает в ownCloud, а его содержимое сохраняется в S3. Таким образом, подрядчик не видит, какие еще файлы лежат в папке, а мы контролируем, кто, что и когда загрузил.</p><h3>3. Долгосрочный архив креативов и отчетов</h3><p>По закону (152-ФЗ в РФ или GDPR в Европе) компания обязана хранить персональные данные клиентов, а также отчеты о рассылках и рекламных акциях на протяжении определенного времени.</p><p>Для решения этой задачи мы настроили правило: файлы старше 90 дней автоматически перемещаются в S3 Glacier (холодное хранилище) – этот класс снижает стоимость хранения, а если, например, юристу понадобится скачать какой-нибудь отчет спустя 2–3 года, он просто выгрузит его из ownCloud буквально за 5–10 минут.</p><p>Теперь – в деталях и по шагам о том, как начать использовать ownCloud в связке с S3.</p><h2>Как развернуть ownCloud и подключить S3</h2><p>OwnCloud удобно использовать с объектным хранилищем S3 – таким образом можно:</p><ol><li>масштабировать систему – S3 расширяется автоматически и не имеет ограничений по объему и количеству размещаемых данных и файлов;</li><li>оптимизировать затраты – можно платить не за дорогую конфигурацию виртуального сервера с большим объемом диска, а лишь за фактически занимаемое место, по модели pay as you go (оплата по мере потребления);</li><li>повысить надежность хранения – за счет встроенной в S3 тройной репликации данных (файлы хранятся в 3 копиях и размещаются на независимых серверах в разных стойках для абсолютной сохранности данных).</li></ol><h3>Итак, разберем, как настроить связку ownCloud и S3.</h3><p>Разработчики ownCloud предлагают два варианта установки. Можно скачать ownCloud и установить его вручную или использовать Docker-контейнеры. Мы выберем второй вариант.</p><p>Для размещения ownCloud в нашем примере создадим виртуальный сервер на базе <a href="https://beget.com/ru/cloud/marketplace/docker">готового решения Docker</a>.</p><p>Можно подключиться к серверу по SSH или с помощью терминала в панели управления.</p><p>Для размещения файлов создайте бакет объектного хранилища S3. Реквизиты доступа к нему будут в карточке бакета в панели:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/ee49d00b-7e32-4b8d-8ad4-bbbaeb0c3bb0.webp" alt="" /></figure><p>Создайте директорию для размещения конфигурационных файлов проекта и перейдите в нее:</p><p>Затем вставьте в файл docker-compose.yml следующее содержимое с помощью любого текстового редактора:</p><p>После этого создайте файл .env, в котором будут храниться значения переменных. Шаблон файла следующий:</p><p>Теперь необходимо отредактировать эти строки:</p><ol><li>ownCloud_DOMAIN и ownCloud_TRUSTED_DOMAINS – укажите домен (так как ownCloud будет размещен за обратным прокси, указывать рабочий порт здесь не требуется);</li><li>ADMIN_USERNAME – логин администратора;</li><li>ADMIN_PASSWORD – пароль администратора.</li></ol><p><i>Обратите внимание! Изменение ADMIN_USERNAME и ADMIN_PASSWORD уже после развертывания контейнеров не возымеет эффекта. Изменить пароль администратора вы можете в настройках пользователя в веб-интерфейсе.</i></p><p>Далее необходимо указать параметры подключения к S3.</p><ul><li>ownCloud_OBJECTSTORE_BUCKET – имя бакета S3;</li><li>ownCloud_OBJECTSTORE_ENDPOINT – эндпоинт хранилища (например, https://s3.ru1.storage.beget.cloud);</li><li>ownCloud_OBJECTSTORE_REGION – регион (ru1 для Beget);</li><li>ownCloud_OBJECTSTORE_KEY – Access key бакета;</li><li>ownCloud_OBJECTSTORE_SECRET – Secret key бакета.</li></ul><p>Сохраните файл.</p><p>Остается лишь добавить файл конфигурации для Caddy – обратного прокси, через который пользователи будут получать доступ к ownCloud.</p><p>Создайте директорию config:</p><p>После чего создайте в ней файл конфигурации Caddyfile. Добавьте в него следующее содержимое, указав вместо ownCloud.betutorial.ru ваш домен ownCloud:</p><p><i>Обратите внимание! Caddy выпустит SSL-сертификат на домен автоматически.</i></p><p>Все запросы к домену будут проксироваться в контейнер ownCloud_server.</p><p>На этом настройка конфигурационных файлов завершена, можно запускать контейнеры:</p><p>Потребуется несколько минут, чтобы docker загрузил образ и развернул контейнеры.</p><p>После запуска перейдите по домену, чтобы проверить работу хранилища:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/934faf67-2939-40f3-840e-88af18ebfde3.webp" alt="" /></figure><p>Выполните вход со стандартными доступами.</p><p><i>Обратите внимание! Если ownCloud недоступен или вы получаете ошибку при входе со стандартными доступами, проверьте корректность конфигурационных файлов. После внесения изменений перезапустите контейнеры.</i></p><p>После входа вы попадете на главную страницу ownCloud. Перед началом работы мы крайне рекомендуем сменить стандартный пароль администратора. Сделать это можно, нажав на кнопку с именем пользователя в верхней правой части страницы и открыв раздел настроек.</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/9f93c25a-3922-4223-b3bd-b45aaaf61edf.webp" alt="" /></figure><p>Теперь проверим работу объектного хранилища – перейдем на главную страницу и загрузим файлы:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/51a6e16f-ee9b-4e96-9a5c-7ef765f62286.webp" alt="" /></figure><p>Файлы также появились и в объектном хранилище:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/16e65ad7-28f9-462c-9af6-990d2cf3c878.webp" alt="" /></figure><p><i>Обратите внимание! Файлы, которые вы удалите в ownCloud, будут перемещены в корзину и останутся в S3. Для их полного удаления очистите корзину ownCloud.</i></p><p>Чтобы делиться паролями с новыми пользователями, необходимо настроить отправку почты в ownCloud, сделать это можно в разделе Settings&gt;General.</p><p>В нашем примере мы настроим отправку через SMTP:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/45e39a41-4bb1-4d19-9bfe-1e1db3afc4a6.webp" alt="" /></figure><p>После указания данных введите тестовый email и нажмите “Send email”. Если отправка успешна, вы получите уведомление об этом:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/5a22786d-3995-4e86-9b48-0a17363c8a18.webp" alt="" /></figure><p>А на почтовый ящик поступит письмо:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/f4043b49-9a17-42ed-a627-34502c2a16e8.webp" alt="" /></figure><p>На этом настройка завершена – можно начинать работать с файлами, используя связку ownCloud и S3.</p><h2>Заключение</h2><p>Если вы ловите себя на мысли, что данных стало настолько много, что поиск нужного файла порой происходит дольше, чем работа с ним (особенно если одни файлы хранятся на почте или в мессенджере, а другие – на ноутбуке или флешке), облачное хранилище может вам помочь.</p><p>Подобное ПО пригодится как для личных целей, так и для бизнеса – недаром в 2025 году в нашей стране был <a href="https://www.kommersant.ru/doc/8178724">зафиксирован</a> рост интереса крупного и среднего бизнеса к технологии облачного хранилища.</p><p>Надеюсь, эта статья была для вас полезна, а облачные хранилища помогут сделать ежедневную работу комфортнее.</p>]]></content:encoded>
    </item>
    <item>
      <title>Denwer SE: Возрождение легендарного локального веб-сервера на современном стеке</title>
      <link>https://tproger.ru/articles/denwer-se-vozrozhdenie-legendarnogo-lokalnogo-veb-servera-na-so</link>
      <comments>https://tproger.ru/articles/denwer-se-vozrozhdenie-legendarnogo-lokalnogo-veb-servera-na-so?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Тишов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/denwer-se-vozrozhdenie-legendarnogo-lokalnogo-veb-servera-na-so</guid>
      <description><![CDATA[<p>Помните диск Z:, иконку джентльмена и магию Run.exe? Денвер вернулся. Denwer SE: Python вместо Perl, HTTPS без красных экранов, свежий PHP и портативность. И да, он всё ещё помещается на флешку.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/denwer-se-vozrozhdenie-legendarnogo-lokalnogo-veb-servera-na-so">Denwer SE: Возрождение легендарного локального веб-сервера на современном стеке</a>»</p>]]></description>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Для продвинутых]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[CMS]]></category>
      <category><![CDATA[Laravel]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 05 May 2026 10:11:34 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы начинали веб-разработку в середине 2000-х, то наверняка помните Denwer — «джентльменский набор веб-разработчика». Иконка в виде человека в шляпе, виртуальный диск Z:, папка <i>home/localhost/www</i> — всё это было ритуалом, который упрощал жизнь тысячам разработчиков. Но оригинальный Denwer безнадёжно устарел: Perl-скрипты, 32-битные сборки, поддержка только древних версий PHP и MySQL. Ему на смену пришли громоздкие комбайны вроде Open Server или сложные для новичков Docker-контейнеры.</p><p>Однако недавно проект получил второе дыхание. Разработчик Александр Тишов (Amro) — создатель <a href="https://seditio.org" rel="nofollow">CMS Seditio</a> и основатель веб-студии <a href="https://avego.org" rel="nofollow">«Авего»</a>  — выпустил <a href="https://seditio.org/dev/denwer-se-lokalnyj-veb-stek-dlya-windows-apache-php-mysql-mariadb" rel="nofollow">Denwer SE (Second Edition)</a>. Это не просто обновление, а полный реинжиниринг с сохранением классической философии: портативность, скорость работы и привычная структура каталогов.</p><p>В этой статье разберём, что изменилось под капотом, почему панель управления переехала с Perl на Python, как работает автоматический HTTPS с собственным корневым сертификатом и зачем нужен зоопарк версий PHP от 5.6 до 8.5.</p><h2>Краткий экскурс: от Denwer 3 до Denwer SE</h2><p>Оригинальный Denwer (сокращение от Джентельменский Набор Веб-разработчика) появился в начале 2000-х. Он представлял собой связку Apache + PHP + MySQL, упакованную в самораспаковывающийся архив. Главные фишки:</p><ul><li>Виртуальный диск (по умолчанию Z:), который монтировался через subst.</li><li>Автоматическое создание виртуальных хостов по именам папок в home.</li><li>Консольные exe-файлы (Run, Stop, Restart) без графического окна.</li></ul><p>Проблемы оригинала:</p><ul><li>Управление на Perl — медленно, тяжело поддерживать в Windows.</li><li>Только 32-битные компоненты.</li><li>Невозможно быстро переключать версии PHP или БД.</li><li>Отсутствие нормального HTTPS (только самоподписанные сертификаты с ошибками в браузере).</li><li>Поддержка прекратилась в 2016 году.</li></ul><p>Denwer SE решает все эти проблемы, оставаясь при этом таким же портативным — достаточно скопировать папку на флешку или в облачный каталог.</p><h2>Архитектура: Python вместо Perl</h2><p>Denwer SE — панель управления написана на Python и скомпилирована в один EXE-файл (через PyInstaller).</p><p>Внутри служебной папки <b>denwer\</b> лежат:</p><ul><li>DLL-версия Python — интерпретатор, который использует основной исполняемый файл.</li><li>Скомпилированные модули .pyd — в том числе GUI на базе Tcl/Tk для оконного интерфейса и системного трея.</li><li>Минимальный набор библиотек для управления службами, правки hosts и генерации сертификатов.</li></ul><p>Это даёт несколько преимуществ:</p><ul><li>Портативность — панель ищет соседние папки home и usr, поэтому каталог со стеком можно переносить куда угодно без переустановки.</li><li>Скорость — Python-скрипты запускаются быстрее, чем Perl, особенно на холодном старте.</li><li>Читаемость кода — разработчику проще поддерживать и расширять функционал.</li></ul><h2>Полный переход на x64</h2><p>Оригинальный Denwer навсегда остался 32-битным, что в современных реалиях просто неприемлемо. Denwer SE собирается исключительно под x64:</p><ul><li>Apache (версия 2.4.x) — 64-битный.</li><li>Все модули PHP (от 5.6 до 8.5) — Thread Safe x64.</li><li>MySQL / MariaDB — 64-битные сборки.</li></ul><p>Системные требования — Windows 7/8/10/11 (x64). Для работы компонентов потребуются Microsoft Visual C++ Redistributable (VC11, VC12, VC14, VC15). Разработчик положил установщики этих пакетов в папку <b>vcredist\</b> — при необходимости можно доустановить вручную.</p><h2>Структура каталогов: преемственность и гибкость</h2><p>Denwer SE сохранил классическую структуру, чтобы старые пользователи не ломали голову:</p><p>Главный конфиг — usr\configuration.txt. В нём задаются пути без жёсткой привязки к букве диска, например:</p><p>При старте панель монтирует виртуальный диск (по умолчанию Z:) и динамически подставляет путь через переменную <b>subst_drive</b>.</p><h2>Управление версиями PHP и БД без танцев с бубном</h2><p>В Denwer SE встроен менеджер версий. Вы просто выбираете из выпадающего списка нужную версию PHP (например, 8.3 или 5.6) — панель сама правит конфигурацию Apache.</p><p>Как это работает под капотом:</p><p>В папке usr/local/apache/php лежат подкаталоги php5.6, php7.4, php8.3 и т.д..</p><p>В каждом из них есть файл php-denwer.conf— шаблон для подключения модуля к Apache. При выборе версии этот файл копируется в <b>conf/extra/httpd-denwer.conf</b>, который затем включается в основной httpd.conf.</p><p>Если вы хотите добавить свою сборку PHP (например, PHP 8.4-rc), достаточно:</p><ul><li>Распаковать x64 Thread Safe версию в отдельный каталог внутри php\.</li><li>Создать php-denwer.conf по образцу.</li><li>Убедиться, что все DLL от VC++ установлены.</li></ul><p>Аналогично для баз данных: переключение между MySQL 5.7 и MariaDB 11.8 происходит через тот же интерфейс. В каталоге СУБД может лежать файл <b>db-denwer.conf</b>, который при старте копируется в <b>my.ini</b>.</p><h2>HTTPS, который не бесит: локальный Root CA</h2><p>Самое болезненное место при локальной разработке это самоподписанные сертификаты. Браузеры постоянно ругаются, приходится кликать «Принять риск». Для командной разработки это вообще катастрофа: каждый участник должен сгенерировать свой сертификат и добавить в исключения.</p><p>Denwer SE решает проблему элегантно — он создаёт собственный корневой центр сертификации (CA) и подписывает им сертификаты для всех ваших локальных доменов.</p><p>Как это работает:</p><ol><li>При первом запуске (если найден OpenSSL) панель генерирует ключи denwer-ca.key и сертификат denwer-ca.crt в папку usr/local/apache/conf/cert/denwer-ca/.</li><li>Для каждого виртуального хоста (папки в home/) автоматически создаётся сертификат в conf/cert/&lt;domain&gt;/.</li><li>Все сертификаты хостов подписаны локальным CA.</li></ol><p>Чтобы браузер доверял им, нужно один раз установить <b>denwer-ca.crt</b> в хранилище «Доверенные корневые центры сертификации» Windows. Для этого в панели есть специальная кнопка (требует прав администратора).</p><p>После этого любые HTTPS-запросы к локальным хостам работают без единого предупреждения.</p><h2>Удобства для разработчика (DX)</h2><p>В версии 1.2.4 добавили несколько фич, которые экономят время каждый день:</p><ul><li>Лог с таймштампами — каждая строка в окне панели имеет префикс [чч:мм:сс]. Теперь видно, сколько секунд сервер поднимается и где возможны задержки.</li><li>Прямой доступ к php.ini и my.cnf — рядом со списками версий появились кнопки, открывающие конфигурацию именно активной версии.</li><li>Автоматическое ведение hosts — панель в реальном времени сканирует home/, находит новые домены и прописывает их в C:\Windows\System32\drivers\etc\hosts. Журнал добавляемых записей сохраняется в usr\AddedHosts.txt. При остановке стека лишние строки удаляются.</li><li>Для смены версии PHP или базы данных панель требует полной остановки всех служб. Вы нажимаете «Стоп», меняете версию в списке, затем «Старт» — и стек поднимается уже с новыми настройками. Автоматический перезапуск без вашего участия работает только для Apache: когда вы добавляете новый домен в папку home/, панель сама переписывает vhosts.conf и перезапускает веб-сервер, не трогая БД.</li></ul><h2>Почему не Open Server или Docker?</h2><p>Этот вопрос закономерно возникает у всех, кто видит очередной локальный веб-сервер. Ведь есть уже давно Open Server Panel, Laragon, XAMPP, а для продвинутых — Docker. Зачем ещё один?</p><p><b>Open Server</b> — мощный и удобный комбайн с десятками версий PHP и настройками «на века». Но он разворачивается в системе не портативно: создаёт папки в ProgramData, пишет в реестр, а запуск может занимать 5–10 секунд. Denwer SE, напротив, полностью переносим: скопировал папку на флешку или в облачный каталог — и всё работает. Запуск стека — буквально 1–2 секунды, что критично, когда вы десятки раз за день перезапускаете сервер для тестов.</p><p><b>Docker</b> — индустриальный стандарт для изоляции и воспроизводимости окружений. Но для локальной разработки простого сайта он часто избыточен. Вам нужно разобраться в образах, контейнерах, пробросе портов, volume’ах и docker-compose.yml. А в Denwer SE вы просто создали папку в home/ — и готово. Никакой работы с командной строкой, никакого потребления гигабайт ОЗУ на фоновую службу Docker Desktop.</p><p><b>Laragon</b> — быстрый, портативный, поддерживает не только PHP, но и Node.js, Python, Go. Но он ориентирован на современные фреймворки, особенно Laravel. Denwer SE же сделан для тех, кто вырос на классическом Денвере: виртуальный диск Z:, папка home/имя_домена/www, минимум настроек. Не нужно переучиваться — просто распаковал и работаешь как 10 лет назад, но с новыми версиями PHP и HTTPS.</p><h2>Как начать пользоваться Denwer SE</h2><ol><li>Скачать архив с <a href="https://seditio.org/dev/denwer-se-lokalnyj-veb-stek-dlya-windows-apache-php-mysql-mariadb" rel="nofollow">официального сайта автора</a>.</li><li>Распаковать в любое место, например C:\web\DenwerSE\.</li><li>Запустить DenwerSE.exe — если нет прав администратора, попросит их для монтирования диска и правки hosts.</li><li>Нажать «Запустить» — появится виртуальный диск Z:, а в системном трее иконка.</li><li>Создать папку сайта — например, home\myproject.local и положить туда index.php.</li><li>Открыть в браузере http://myproject.local/ (или https://myproject.local/). HTTPS будет работать сразу после установки корневого сертификата (кнопка в панели).</li></ol><p>По умолчанию пароль к MySQL/MariaDB — пустая строка (пользователь <b>root</b>). При желании его можно сменить через phpMyAdmin.</p><h2>Заключение</h2><p>Denwer SE — это не просто ностальгический проект. Это действительно современный инструмент, который доказывает, что концепция «локального сервера в одну папку» всё ещё актуальна. Отказ от Perl в пользу Python, менеджер версий PHP/БД, нормальный HTTPS, портативность и мгновенный запуск — всё это делает его отличным выбором для быстрого прототипирования, тестирования легаси-кода или обучения веб-разработке.</p><p>Если вы устали ждать, пока Open Server применит настройки, или не хотите разбираться в Docker Compose — попробуйте <b>Denwer SE</b>. Вероятно, он напомнит вам старые добрые времена, но уже без боли устаревших технологий.</p><ul><li>Автор проекта: Александр Тишов
	(Amro), разработчик CMS Seditio.</li><li>Лицензия: Freeware.</li><li>Совместимость: Windows 7/8/10/11 x64.</li></ul><p>Исходники панели управления не открыты (распространяется скомпилированный EXE), но архитектура и конфиги полностью прозрачны. В планах — добавить поддержку Nginx в качестве альтернативы. Следите за обновлениями.</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL: полный путеводитель — от первых запросов до оконных функций</title>
      <link>https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij</link>
      <comments>https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Картофельный Повелитель]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij</guid>
      <description><![CDATA[<p>Полный гайд по SQL: команды, транзакции ACID, нормализация, оконные функции, PostgreSQL, защита от инъекций. Разберитесь в SQL от нуля до уверенного уровня.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij">SQL: полный путеводитель — от первых запросов до оконных функций</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 03 Apr 2026 03:12:28 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>SQL</b> (Structured Query Language) — язык запросов для работы с реляционными базами данных, который появился больше 50 лет назад и остаётся одним из самых востребованных навыков в IT. По данным <a href="https://survey.stackoverflow.co/2024/technology/">Stack Overflow Developer Survey 2024</a>, SQL стабильно входит в тройку самых используемых языков — его применяют бэкендеры, аналитики данных, дата-инженеры и тестировщики.</p><p>Этот путеводитель — не просто список ссылок. Каждая секция содержит самостоятельный разбор темы: от истории SQL и принципов работы реляционных баз до транзакций, нормализации и защиты от инъекций. Там, где тема заслуживает глубокого погружения, мы даём ссылку на отдельную статью. Цель — дать полную карту знаний, по которой можно выстроить обучение от нуля до уверенного уровня.</p><p>— SQL — фундаментальный навык для любого, кто работает с данными: от джуна до архитектора</p><p>— Основные команды (SELECT, JOIN, GROUP BY) покрывают 80% повседневных задач</p><p>— Порядок выполнения запроса (FROM → WHERE → GROUP BY → SELECT) — ключ к пониманию SQL</p><p>— Транзакции, ACID и уровни изоляции гарантируют надёжность данных</p><p>— Оконные функции, CTE и хранимые процедуры — продвинутый уровень для карьерного роста</p><p>— PostgreSQL — СУБД №1 в 2024 по Stack Overflow Survey, обогнавшая MySQL</p><p>— SQL не устареет: стандарт развивается, появляются JSON-запросы и графовый SQL</p><h2>Что такое SQL и зачем его учить</h2><p><b>SQL</b> (Structured Query Language) — декларативный язык для работы с реляционными базами данных. «Декларативный» означает, что вы описываете <i>что</i> хотите получить, а не <i>как</i> это сделать. Вы пишете «дай мне все заказы за март», а СУБД сама решает, в каком порядке обходить таблицы и какие индексы использовать.</p><p>Краткая история: в 1970 году Эдгар Кодд из IBM опубликовал реляционную модель данных. В 1974 Дональд Чемберлин и Рэймонд Бойс создали язык SEQUEL (Structured English Query Language) для работы с этой моделью. Позже его переименовали в SQL из-за торговой марки. В 1986 году ANSI принял SQL как стандарт, а последняя версия — SQL:2023 — добавила поддержку JSON и графовых запросов.</p><p>Его используют бэкендеры, аналитики, дата-инженеры и даже тестировщики. И в обозримом будущем SQL никуда не денется — язык продолжает развиваться вместе со стандартом.</p><h2>Как работает SQL: от запроса до результата</h2><p>Когда вы отправляете SQL-запрос, внутри СУБД происходит цепочка шагов:</p><ol><li><b>Парсинг</b> — СУБД разбирает текст запроса, проверяет синтаксис и строит дерево разбора</li><li><b>Анализ</b> — проверяет, существуют ли таблицы и столбцы, есть ли у пользователя права доступа</li><li><b>Оптимизация</b> — самый важный этап. Оптимизатор строит несколько вариантов плана выполнения и выбирает самый дешёвый по стоимости (I/O, CPU, память)</li><li><b>Выполнение</b> — движок исполняет выбранный план: сканирует таблицы, применяет фильтры, объединяет результаты</li><li><b>Возврат результата</b> — СУБД формирует набор строк и отправляет клиенту</li></ol><h3>Логический порядок выполнения запроса</h3><p>SQL-запрос пишется в одном порядке, а выполняется в другом. Вот реальная последовательность обработки:</p><ol><li>FROM / JOIN — определяется источник данных, выполняются соединения</li><li>WHERE — фильтрация строк (до группировки)</li><li>GROUP BY — группировка</li><li>HAVING — фильтрация групп (после группировки)</li><li>WINDOW — вычисление оконных функций</li><li>SELECT — выбор столбцов, вычисление выражений и алиасов</li><li>DISTINCT — удаление дублей</li><li>ORDER BY — сортировка (по стандарту SQL единственное место, где гарантированно работает алиас из SELECT (в PostgreSQL и MySQL алиасы также работают в GROUP BY))</li><li>LIMIT / OFFSET — ограничение количества строк</li></ol><p>Из-за этого порядка нельзя использовать алиас из SELECT в WHERE — на момент фильтрации SELECT ещё не выполнен. А HAVING работает после GROUP BY, поэтому в нём доступны агрегатные функции.</p><p>Именно благодаря оптимизатору SQL остаётся эффективным: вы пишете простой запрос, а СУБД сама выбирает, использовать ли индекс, в каком порядке объединять таблицы, нужна ли сортировка. Увидеть план выполнения можно командой EXPLAIN ANALYZE — это один из главных инструментов оптимизации.</p><h2>Основные команды SQL</h2><p>Любое знакомство с SQL начинается с четвёрки CRUD: SELECT (чтение), INSERT (создание), UPDATE (изменение), DELETE (удаление). К ним добавляются DDL-команды для управления структурой: CREATE TABLE, ALTER TABLE, DROP TABLE, TRUNCATE TABLE (быстрое удаление всех строк без логирования каждой).</p><p>Реальная мощь SQL раскрывается в объединениях через JOIN (INNER, LEFT, RIGHT, FULL), группировке с GROUP BY и фильтрации агрегатов через HAVING. Пример: найти средний чек по городам, где было больше 100 заказов: А также CROSS JOIN (декартово произведение всех строк) и SELF JOIN (соединение таблицы с собой — например, для поиска сотрудников и их руководителей).</p><p>На практике эти команды покрывают примерно 80% задач. Полный разбор с примерами — в нашем <a href="https://tproger.ru/translations/sql-recap">гайде по основным командам SQL</a>. Статью прочитали полтора миллиона раз.</p><h2>Типы данных и ограничения SQL</h2><p>Правильный выбор типов данных — основа производительной и надёжной базы. Базовые типы SQL:</p><ul><li><b>Числовые:</b> INTEGER, BIGINT, DECIMAL(10,2), FLOAT</li><li><b>Строковые:</b> VARCHAR(255), TEXT, CHAR(10)</li><li><b>Дата и время:</b> DATE, TIMESTAMP, INTERVAL</li><li><b>Логический:</b> BOOLEAN</li><li><b>JSON:</b> JSON / JSONB (PostgreSQL) — для полуструктурированных данных</li></ul><p>Ограничения (constraints) — это правила, которые СУБД проверяет автоматически при каждой вставке и обновлении:</p><p>PRIMARY KEY гарантирует уникальность строки. FOREIGN KEY связывает таблицы и не даёт создать «висячие» ссылки. NOT NULL запрещает пустые значения. CHECK валидирует данные по условию. Вместе эти ограничения защищают целостность данных на уровне структуры — СУБД не позволит вставить строку, нарушающую правила.</p><h2>Операторы и выражения</h2><p>За базовыми командами идут операторы, которые делают запросы по-настоящему гибкими. WHERE фильтрует строки, LIKE ищет по шаблону с подстановочными знаками (% — любая подстрока, _ — один символ), IN проверяет вхождение в список, BETWEEN задаёт диапазон.</p><p>Отдельного внимания заслуживает CASE WHEN — условная логика прямо внутри запроса:</p><p>Подробный разбор LIKE с примерами — в <a href="https://tproger.ru/articles/like-sql">отдельной статье</a>.</p><h3>NULL: подводные камни</h3><p>NULL — не значение, а отсутствие значения. NULL = NULL возвращает не TRUE, а NULL. Единственный способ проверки — IS NULL / IS NOT NULL.</p><h3>Функции даты и времени</h3><p>Работа с датами — повседневная задача аналитика:</p><ul><li>NOW() / CURRENT_DATE — текущий момент / дата</li><li>DATE_TRUNC('month', ts) — округление до начала периода</li><li>EXTRACT(YEAR FROM ts) — извлечение части даты</li><li>ts + INTERVAL '7 days' — арифметика с датами</li></ul><h3>Строковые и математические функции</h3><p>Помимо дат и агрегатов, SQL предоставляет богатый набор функций для работы со строками и числами. Строковые функции: CONCAT — склейка строк, SUBSTRING — извлечение подстроки, LENGTH — длина строки, UPPER / LOWER — смена регистра, REPLACE — замена подстроки, TRIM — удаление пробелов по краям. Математические: ROUND — округление, ABS — модуль числа, CEIL / FLOOR — округление вверх и вниз. Эти функции работают одинаково в PostgreSQL, MySQL и других СУБД (с минимальными различиями в именах).</p><h3>Операторы множеств: UNION, INTERSECT, EXCEPT</h3><p>Эти операторы объединяют результаты нескольких запросов:</p><ul><li>UNION — объединение с удалением дубликатов. UNION ALL — без удаления (быстрее)</li><li>INTERSECT — пересечение (строки из обоих запросов)</li><li>EXCEPT — разность (строки из первого, которых нет во втором)</li></ul><h2>Агрегатные функции SQL</h2><p>Агрегатные функции вычисляют одно значение по набору строк: COUNT, SUM, AVG, MIN, MAX. Работают в связке с GROUP BY.</p><p>Нюансы, которые часто путают:</p><ul><li>COUNT(*) считает все строки (включая NULL). COUNT(column) — только строки, где column не NULL</li><li>COUNT(DISTINCT column) — количество уникальных значений</li><li>AVG игнорирует NULL — если NULL означает «0», результат будет завышен</li></ul><h2>Подзапросы, CTE и представления</h2><p>Когда запрос становится сложным, его нужно декомпозировать. Для этого есть три инструмента.</p><h3>Подзапросы</h3><p>Запрос внутри запроса. Бывают скалярные (возвращают одно значение), табличные (набор строк) и коррелированные (ссылаются на внешний запрос):</p><h3>CTE (Common Table Expressions)</h3><p>Конструкция WITH позволяет дать имя подзапросу и переиспользовать его. CTE делают сложные запросы читаемыми, а рекурсивные CTE позволяют обходить деревья и графы:</p><h3>Рекурсивные CTE</h3><p>Рекурсивные CTE обходят деревья и графы — например, оргструктуру компании или вложенные категории:</p><h3>Представления (Views)</h3><p>CREATE VIEW создаёт «виртуальную таблицу» — именованный запрос, к которому можно обращаться как к обычной таблице. Это удобно для инкапсуляции сложной логики и разграничения доступа. Материализованные представления (MATERIALIZED VIEW в PostgreSQL) хранят результат физически и обновляются по команде — полезно для тяжёлых аналитических запросов.</p><h2>Хранимые процедуры и функции</h2><p>Хранимые процедуры и функции — SQL-код, сохранённый на сервере СУБД. Функция возвращает значение и вызывается в SELECT, процедура выполняет действия и вызывается через CALL.</p><p>Когда использовать:</p><ul><li>Инкапсуляция бизнес-логики на уровне базы (расчёт скидок, начисление бонусов)</li><li>Повторяющиеся многошаговые операции (ежемесячные отчёты, архивация)</li><li>Безопасность: SECURITY DEFINER позволяет давать доступ к функции, не давая доступ к таблицам</li></ul><p>Когда <b>не</b> использовать:</p><ul><li>Логику приложения лучше держать в коде — её проще тестировать и деплоить</li><li>Тяжёлые вычисления: масштабировать сервер СУБД дороже, чем сервер приложения</li><li>Бизнес-логика, которая часто меняется — миграции хранимых процедур болезненнее, чем код</li></ul><p>Триггеры — особый тип: они срабатывают автоматически при INSERT/UPDATE/DELETE. Полезны для аудита (логировать все изменения) и автоматических вычислений, но злоупотреблять не стоит — скрытая логика усложняет отладку.</p><h2>Оконные функции SQL</h2><p>Оконные функции — это то, что отделяет новичка от уверенного SQL-разработчика. Они выполняют вычисления по «окну» строк, не сворачивая результат как GROUP BY. Вы получаете и агрегат, и исходные строки одновременно.</p><p>Ключевые функции: ROW_NUMBER() для нумерации, RANK() / DENSE_RANK() для ранжирования, LAG() / LEAD() для сравнения с соседними строками, агрегатные функции с OVER() для скользящих средних и нарастающих итогов.</p><p>Типичные задачи: топ-N в каждой группе, рост метрики месяц к месяцу, скользящее среднее за 7 дней. Без оконных функций эти задачи требуют громоздких подзапросов.</p><p>RANK() пропускает позиции после одинаковых значений (1, 2, 2, 4), а DENSE_RANK() — нет (1, 2, 2, 3). Для скользящих агрегатов используется конструкция ROWS BETWEEN — например, ROWS BETWEEN 6 PRECEDING AND CURRENT ROW для скользящего среднего за 7 дней.</p><p>Детальный разбор с визуальными примерами — в нашей <a href="https://tproger.ru/translations/sql-window-functions">статье об оконных функциях SQL</a>.</p><h2>Транзакции и ACID в SQL</h2><p>Транзакция — группа операций, которые выполняются как единое целое: либо всё, либо ни одна. Классический пример — перевод денег:</p><p>Если между двумя UPDATE произойдёт сбой, ROLLBACK откатит обе операции — деньги не потеряются и не удвоятся. Для частичного отката используется SAVEPOINT: можно откатить транзакцию не целиком, а до определённой точки (ROLLBACK TO SAVEPOINT имя).</p><p>Свойства ACID гарантируют надёжность транзакций:</p><ul><li><b>Atomicity</b> (атомарность) — транзакция неделима: либо выполнена полностью, либо отменена целиком</li><li><b>Consistency</b> (согласованность) — после транзакции база остаётся в корректном состоянии, все ограничения соблюдены</li><li><b>Isolation</b> (изоляция) — параллельные транзакции не мешают друг другу. Уровни: от READ UNCOMMITTED (быстро, но грязные чтения) до SERIALIZABLE (безопасно, но медленно)</li><li><b>Durability</b> (долговечность) — после COMMIT данные сохранены даже при аварии сервера</li></ul><p>ACID — фундамент надёжности реляционных баз данных. Именно эти свойства гарантируют, что данные не потеряются и не «рассинхронятся» даже при сбоях и параллельных запросах.</p><h3>Уровни изоляции</h3><p>Свойство Isolation на практике настраивается через уровни изоляции. Каждый уровень — компромисс между корректностью и производительностью:</p><ul><li><b>READ UNCOMMITTED</b> — самый слабый: видны незакоммиченные изменения других транзакций (dirty reads). Практически не используется</li><li><b>READ COMMITTED</b> — видны только закоммиченные данные. <b>По умолчанию в PostgreSQL</b>. Достаточно для большинства приложений</li><li><b>REPEATABLE READ</b> — повторное чтение строки всегда даёт тот же результат. <b>По умолчанию в MySQL</b>. Защищает от non-repeatable reads</li><li><b>SERIALIZABLE</b> — максимальная изоляция, транзакции ведут себя как последовательные. Нужен для финансовых операций и бронирований</li></ul><h2>Нормализация и проектирование схем</h2><p>Нормализация — процесс организации таблиц так, чтобы минимизировать дублирование данных и аномалии при вставке, обновлении и удалении.</p><p>Три ключевые нормальные формы:</p><ol><li><b>1NF</b> — каждая ячейка содержит одно атомарное значение. Никаких «Москва, Питер» в одном поле — разносим по строкам или связанным таблицам</li><li><b>2NF</b> — все неключевые столбцы зависят от всего первичного ключа, а не от его части. Актуально для составных ключей</li><li><b>3NF</b> — неключевые столбцы не зависят друг от друга. Если город определяет страну, нужна отдельная таблица городов</li></ol><p>Пример: таблица заказов до и после нормализации до 3NF:</p><p>В этом примере мы устранили дублирование данных клиента (2NF). Для полной 3NF нужно было бы вынести и города в отдельную таблицу, если город определяет дополнительные атрибуты (страну, регион).</p><p>На практике большинство баз проектируют в 3NF. Но иногда данные намеренно денормализуют — например, в аналитических хранилищах (OLAP), где скорость чтения важнее экономии места. Схемы «звезда» и «снежинка» в data warehouse — это контролируемая денормализация.</p><h2>Производительность и оптимизация</h2><p>Когда таблица вырастает до миллионов строк, наивные запросы начинают тормозить. Первый инструмент диагностики — EXPLAIN ANALYZE: он показывает, какой план выбрал оптимизатор, сколько строк просканировал и где узкое место.</p><p>Типичные антипаттерны:</p><ul><li>SELECT * вместо конкретных столбцов — читает больше данных, чем нужно</li><li>Отсутствие индекса на столбцах в WHERE и JOIN — приводит к полному сканированию таблицы (Seq Scan)</li><li>Функции на индексированных столбцах: WHERE UPPER(email) = ... — индекс не используется</li><li>N+1 запросы из ORM — 1 запрос за список + N запросов за детали каждой записи</li></ul><p>Индексы — главный способ ускорения. B-tree индекс (по умолчанию) подходит для большинства задач: точные совпадения, диапазоны, сортировка. PostgreSQL также поддерживает GiST (геоданные), GIN (полнотекстовый поиск, JSONB) и BRIN (временные ряды).</p><p>Глубокий разбор типов индексов и их применения — в <a href="https://tproger.ru/articles/indeksy-v-postgresql">нашей статье об индексах PostgreSQL</a>.</p><h2>Безопасность: SQL-инъекции</h2><p>SQL-инъекция — одна из самых опасных уязвимостей веб-приложений, стабильно входящая в <a href="https://owasp.org/Top10/">OWASP Top 10</a>. Суть: если пользовательский ввод подставляется в запрос без обработки, злоумышленник может изменить логику запроса.</p><p>Классический пример — форма логина:</p><p>Защита проста и надёжна — <b>параметризованные запросы</b> (prepared statements):</p><p>Пароли в реальных приложениях никогда не хранят и не сравнивают в открытом виде — их хешируют (bcrypt, argon2), а проверку выполняет код приложения, не SQL-запрос.</p><p>При использовании ORM (SQLAlchemy, Django ORM, Prisma) параметризация происходит автоматически. Если пишете raw SQL — никогда не вставляйте пользовательский ввод через конкатенацию строк или f-строки.</p><h3>Управление доступом: GRANT и REVOKE</h3><p>Вторая линия защиты — принцип минимальных привилегий. Приложению не нужен суперпользователь базы данных:</p><p>REVOKE отзывает права. В PostgreSQL также доступна Row-Level Security (RLS) — ограничение видимости строк в зависимости от роли: каждый менеджер видит только своих клиентов.</p><h2>Современный SQL: JSON, диалекты и стандарт SQL:2023</h2><p>SQL — не замороженный язык из 80-х. Стандарт активно развивается, и последняя версия SQL:2023 (опубликована в июне 2023) принесла два крупных нововведения:</p><ul><li><b>SQL/JSON</b> — стандартизированные функции для работы с JSON прямо в SQL-запросах. PostgreSQL поддерживает JSONB с 2014 года, а теперь аналогичные возможности появляются и в других СУБД</li><li><b>SQL/PGQ</b> (Property Graph Queries) — графовые запросы внутри SQL. Можно искать пути и паттерны в связанных данных без отдельной графовой базы</li></ul><p>На практике каждая СУБД имеет свой диалект:</p><ul><li><b>PostgreSQL</b> — PL/pgSQL, JSONB, массивы, расширения (PostGIS, pg_trgm). Ближе всего к стандарту</li><li><b>MySQL</b> — оконные функции появились поздно — только в версии 8.0 (2018), LIMIT вместо FETCH FIRST</li><li><b>T-SQL</b> (Microsoft SQL Server) — TOP вместо LIMIT, IDENTITY вместо SERIAL, мощные CTE</li><li><b>PL/SQL</b> (Oracle) — ROWNUM, CONNECT BY для иерархий, пакеты (packages)</li><li><b>Cloud SQL</b> — BigQuery, Redshift, Snowflake имеют свои расширения, но базовый SQL везде одинаков</li></ul><p>Хорошая новость: базовый синтаксис (SELECT, JOIN, GROUP BY, оконные функции) одинаков во всех диалектах. Освоив стандартный SQL на PostgreSQL, вы легко перейдёте на любую другую СУБД.</p><h2>PostgreSQL и MySQL</h2><h3>PostgreSQL</h3><p>PostgreSQL — самая популярная реляционная СУБД для новых проектов. Полная поддержка SQL-стандарта, JSONB для полуструктурированных данных, расширения (PostGIS для геоданных, pg_trgm для нечёткого поиска), продвинутая система типов и отличная производительность.</p><p>15 самых полезных команд PostgreSQL — от размера базы до профилирования запросов — в нашей <a href="https://tproger.ru/translations/useful-postgresql-commands">подборке</a>. А для оптимизации больших таблиц — <a href="https://tproger.ru/articles/indeksy-v-postgresql">разбор индексов PostgreSQL</a>.</p><h3>MySQL</h3><p>MySQL — одна из старейших популярных open-source СУБД, движок WordPress и множества legacy-систем. Проще в настройке, но имеет подводные камни: неявное приведение типов, особенности GROUP BY, различия между InnoDB и MyISAM.</p><p>Самые частые ошибки — от кодировок до потери данных — в нашей <a href="https://tproger.ru/translations/troubleshoot-common-errors-in-mysql">статье о типичных ошибках MySQL</a>.</p><h2>Выбор СУБД: SQL vs NoSQL</h2><p>SQLite — для встраиваемых сценариев: мобильные приложения, Electron, edge computing, прототипы (вся база в одном файле). MySQL — проверенный выбор для веб-приложений, на нём работают GitHub и Booking.com. PostgreSQL — универсальный вариант для новых проектов, от стартапов до enterprise. Детальное сравнение с бенчмарками — в <a href="https://tproger.ru/translations/sqlite-mysql-postgresql-comparison">нашем обзоре трёх СУБД</a>.</p><p>Когда данные неструктурированные или нужна горизонтальная масштабируемость, рассмотрите NoSQL: MongoDB (документы), Redis (ключ-значение), Cassandra (колонки), Neo4j (графы). Подробнее — в <a href="https://tproger.ru/translations/sql-nosql-database-models">статье о моделях баз данных</a>.</p><h2>SQL на собеседованиях</h2><p>SQL-вопросы — обязательная часть собеседований для бэкенд-разработчиков, аналитиков и дата-инженеров. Типичный формат: дают схему из 2–3 таблиц и просят написать запрос. Темы: JOIN-ы, GROUP BY, оконные функции, подзапросы, нормализация.</p><p>Ключ к успеху — практика на реальных задачах. Интервьюеры оценивают умение декомпозировать задачу, выбрать правильный тип JOIN и грамотно обработать NULL.</p><p>27 самых распространённых вопросов с ответами — в <a href="https://tproger.ru/articles/sql-interview-questions">нашей подборке</a>. Для практики — <a href="https://tproger.ru/articles/5-zadanij-po-sql-s-realnyh-sobesedovanij">5 заданий с реальных собеседований</a> с разбором решений.</p><h2>Куда двигаться дальше</h2><p>SQL — это фундамент, но не потолок. Направления для роста:</p><ol><li><b>Администрирование БД</b> — репликация, бэкапы, мониторинг, настройка производительности</li><li><b>Дата-инженерия</b> — ETL-пайплайны, dbt, Airflow, data warehouse (BigQuery, Snowflake)</li><li><b>Аналитика данных</b> — SQL + Python (pandas), визуализация, A/B-тесты</li><li><b>Бэкенд-разработка</b> — ORM (SQLAlchemy, Prisma, GORM), миграции, проектирование схем</li><li><b>Data Science</b> — feature engineering, работа с большими датасетами</li></ol><p>Главный совет: практикуйтесь на реальных данных. Поднимите PostgreSQL локально, загрузите публичный датасет и решайте задачи. Ресурсы для старта:</p><ul><li><b><a href="https://sqlbolt.com/">SQLBolt</a></b> — интерактивные уроки SQL в браузере, от нуля</li><li><b><a href="https://pgexercises.com/">PostgreSQL Exercises</a></b> — задачи на реальной схеме (клуб, бронирования)</li><li><b>LeetCode / HackerRank</b> — SQL-задачи для подготовки к собеседованиям</li><li><b><a href="https://www.kaggle.com/datasets">Kaggle Datasets</a></b> — открытые датасеты для импорта в PostgreSQL и экспериментов</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Что такое SQL: основы языка запросов для начинающих</title>
      <link>https://tproger.ru/articles/chto-takoe-sql--osnovy-yazyka-zaprosov-dlya-nachinayushhih</link>
      <comments>https://tproger.ru/articles/chto-takoe-sql--osnovy-yazyka-zaprosov-dlya-nachinayushhih?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-takoe-sql--osnovy-yazyka-zaprosov-dlya-nachinayushhih</guid>
      <description><![CDATA[<p>SQL — язык запросов к базам данных. Разбираем SELECT, INSERT, JOIN, WHERE с примерами, типы данных, сравнение СУБД. Начните писать запросы уже сегодня.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-takoe-sql--osnovy-yazyka-zaprosov-dlya-nachinayushhih">Что такое SQL: основы языка запросов для начинающих</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 29 Mar 2026 05:09:29 GMT</pubDate>
      <content:encoded><![CDATA[<p>Каждый разработчик рано или поздно сталкивается с базами данных. Неважно, пишете ли вы веб-приложение, мобильный сервис или скрипт для анализа данных — в основе почти всегда лежит реляционная база данных, а значит, SQL. Этот язык не устаревает десятилетиями: он появился в 1970-х годах и до сих пор остаётся стандартом де-факто для работы с данными. По данным опроса Stack Overflow Developer Survey 2023, SQL занимает третье место среди профессиональных разработчиков — его используют 51,5% из них (Stack Overflow Developer Survey 2023).</p><p><b>SQL (Structured Query Language)</b> — это декларативный язык запросов для управления реляционными базами данных. С его помощью можно создавать таблицы, добавлять, изменять и удалять данные, а также делать выборки по заданным условиям. SQL стандартизирован организацией ISO и поддерживается всеми основными СУБД: PostgreSQL, MySQL, SQLite, Microsoft SQL Server и Oracle.</p><p>- SQL расшифровывается как Structured Query Language — язык структурированных запросов.</p><p>- Язык создан в 1973 году в IBM, стандарт ISO принят в 1987 году.</p><p>- SQL используют 51,5% профессиональных разработчиков по всему миру (Stack Overflow, 2023).</p><p>- Основные операции: SELECT, INSERT, UPDATE, DELETE — охватывают 90% повседневных задач.</p><p>- SQL работает с реляционными базами данных, где данные хранятся в связанных таблицах.</p><p>- Один SQL-запрос может обработать миллионы строк за доли секунды.</p><h2>Зачем нужен SQL — где используется и кому пригодится</h2><p>SQL нужен везде, где есть структурированные данные. Вот лишь несколько примеров из реальной практики:</p><ul><li><b>Веб-разработка</b> — интернет-магазины, блоги, социальные сети хранят пользователей, товары и записи в реляционных БД.</li><li><b>Аналитика данных</b> — аналитики используют SQL для агрегации, фильтрации и построения отчётов.</li><li><b>Backend-разработка</b> — серверные приложения взаимодействуют с PostgreSQL или MySQL через SQL-запросы.</li><li><b>Data Science</b> — учёные по данным выгружают датасеты из хранилищ (Redshift, BigQuery) с помощью SQL.</li><li><b>DevOps и администрирование</b> — DBA оптимизируют запросы, настраивают индексы, следят за производительностью.</li></ul><p>SQL востребован как у начинающих разработчиков, так и у опытных инженеров. По данным Glassdoor, знание SQL входит в топ-3 навыков для вакансий Data Analyst и Backend Developer в 2024 году. Даже фронтендеры, которые редко работают напрямую с БД, рано или поздно сталкиваются с SQL при отладке или настройке.</p><h2>Основные команды SQL</h2><p>Все команды SQL делятся на группы. Самые важные — это DDL (Data Definition Language) для создания структур и DML (Data Manipulation Language) для работы с данными. Рассмотрим ключевые команды подробнее.</p><h3>SELECT — выборка данных</h3><p>SELECT — самая используемая команда SQL. Она позволяет извлекать данные из одной или нескольких таблиц. Базовый синтаксис:</p><p>Звёздочка * означает «все столбцы», но на практике лучше перечислять нужные явно — это ускоряет запрос и делает код читаемым. Чтобы отфильтровать дубликаты, используют SELECT DISTINCT.</p><p>Можно также ограничить количество строк в результате:</p><h3>INSERT, UPDATE, DELETE — изменение данных</h3><p>Три команды, отвечающие за создание, изменение и удаление записей:</p><p><b>Важно:</b>
Всегда используйте WHERE в командах UPDATE и DELETE. Без условия изменения применятся ко всем строкам таблицы, и восстановить данные без бэкапа не получится.</p><h3>CREATE TABLE — создание таблиц</h3><p>Прежде чем работать с данными, нужно создать таблицу. Команда CREATE TABLE задаёт структуру: имена столбцов, их типы и ограничения:</p><p>SERIAL (или AUTO_INCREMENT в MySQL) автоматически генерирует уникальный числовой идентификатор. PRIMARY KEY — уникальный ключ строки. REFERENCES создаёт внешний ключ — связь между таблицами.</p><h3>JOIN — объединение таблиц</h3><p>Реляционные базы данных хранят информацию в нескольких связанных таблицах. Чтобы получить данные из нескольких таблиц одним запросом, используется JOIN. Существует несколько видов объединений:</p><ul><li>INNER JOIN — только совпадающие строки из обеих таблиц.</li><li>LEFT JOIN — все строки из левой таблицы, совпадения из правой (или NULL).</li><li>RIGHT JOIN — все строки из правой таблицы, совпадения из левой (или NULL).</li><li>FULL OUTER JOIN — все строки из обеих таблиц, NULL там, где нет совпадений.</li></ul><h3>WHERE, ORDER BY, GROUP BY — фильтрация и сортировка</h3><p>Три важнейших инструмента для управления результатом выборки. Подробный разбор ORDER BY с примерами читайте в нашем <a href="https://tproger.ru/articles/sortirovka-v-sql--order-by--asc-i-desc-s-primerami">гайде по сортировке в SQL</a>.</p><p>Ключевое отличие: WHERE фильтрует строки <i>до</i> группировки, HAVING — <i>после</i>. Агрегатные функции (COUNT, SUM, AVG, MIN, MAX) работают с группами строк.</p><h2>Типы данных в SQL</h2><p>При создании таблицы каждому столбцу нужно указать тип данных. Правильный выбор типа экономит место на диске и ускоряет запросы. Основные типы:</p><ul><li><b>Числовые:</b> INT / INTEGER — целые числа; BIGINT — большие целые; DECIMAL(p,s) — дробные с фиксированной точностью; FLOAT — числа с плавающей запятой.</li><li><b>Строковые:</b> VARCHAR(n) — строка до n символов; TEXT — строка без ограничений; CHAR(n) — строка фиксированной длины.</li><li><b>Дата и время:</b> DATE — дата (YYYY-MM-DD); TIME — время; TIMESTAMP — дата и время; INTERVAL — интервал.</li><li><b>Логический:</b> BOOLEAN — значения TRUE / FALSE / NULL.</li><li><b>Специальные:</b> UUID — уникальный идентификатор; JSON / JSONB — JSON-данные (PostgreSQL); ARRAY — массив значений.</li></ul><p>Практическое правило: используйте наименьший подходящий тип. Для возраста достаточно SMALLINT, для идентификатора пользователя — INT, для финансовых сумм — DECIMAL, а не FLOAT (чтобы избежать ошибок округления).</p><h2>SQL vs NoSQL — когда что использовать</h2><p>SQL-базы данных хранят данные в таблицах с фиксированной схемой. NoSQL-базы (MongoDB, Redis, Cassandra) используют другие модели: документы, ключ-значение, графы, колонки. Вот когда выбирать каждый подход:</p><ul><li><b>SQL подходит, когда:</b> данные структурированы и схема стабильна; важна целостность и транзакции (банки, интернет-магазины); нужны сложные запросы с JOIN и агрегацией; команда умеет работать с реляционными БД.</li><li><b>NoSQL подходит, когда:</b> структура данных гибкая или меняется часто; нужна горизонтальная масштабируемость под огромные объёмы; данные неструктурированы (логи, события, JSON); требуется сверхнизкая латентность (кэш в Redis).</li></ul><blockquote>SQL и NoSQL — не конкуренты, а инструменты для разных задач. В одном проекте вполне можно использовать PostgreSQL для бизнес-данных и Redis для кэша.</blockquote><h2>Популярные СУБД: PostgreSQL, MySQL, SQLite, MS SQL</h2><p>SQL-синтаксис стандартизирован, но каждая СУБД добавляет свои расширения. Вот краткое сравнение четырёх самых популярных:</p><ul><li><b>PostgreSQL</b> — мощная open-source СУБД с богатым набором типов данных, поддержкой JSON, полнотекстового поиска и оконных функций. Лучший выбор для серьёзных проектов. Подробнее читайте в нашем <a href="https://tproger.ru/articles/osnovy-postgresql-dlya-nachinayuschih--rukovodstvo-s-primerami">руководстве по PostgreSQL для начинающих</a>.</li><li><b>MySQL / MariaDB</b> — самая распространённая СУБД для веб-приложений, особенно в связке с PHP (WordPress, Drupal). Простая в настройке, быстрая для чтения.</li><li><b>SQLite</b> — встроенная база данных в одном файле, без сервера. Идеально подходит для мобильных приложений, тестирования и небольших проектов. Используется в Android, iOS, браузерах.</li><li><b>Microsoft SQL Server</b> — корпоративная СУБД от Microsoft, тесно интегрированная с экосистемой .NET и Azure. Популярна в крупных компаниях.</li></ul><p>Если вы только начинаете, рекомендуем PostgreSQL или SQLite. PostgreSQL — для полноценной разработки, SQLite — для обучения без установки сервера.</p><h2>Как начать учить SQL — ресурсы, песочницы, советы</h2><p>SQL — один из самых практичных языков для изучения. Базовые команды можно освоить за неделю, а первые реальные запросы писать уже через несколько часов практики.</p><p>Подробную дорожную карту с последовательностью тем и рекомендуемыми ресурсами смотрите в нашей <a href="https://tproger.ru/articles/dorozhnaya-karta-sql-dlya-nachinayuschih-v-2024-godu">дорожной карте SQL для начинающих</a>.</p><ul><li><b>SQLiteOnline.com</b> — онлайн-песочница без регистрации. Запустите первый запрос прямо в браузере за 30 секунд.</li><li><b>SQLBolt.com</b> — интерактивный курс с упражнениями от SELECT до сложных JOIN. Полностью бесплатный, на английском.</li><li><b>Stepik.org</b> — бесплатный курс «Введение в базы данных» на русском языке с практическими заданиями.</li><li><b>LeetCode / HackerRank</b> — задачи на SQL для подготовки к техническим собеседованиям.</li><li><b>Официальная документация PostgreSQL</b> — самый полный и точный источник по возможностям СУБД.</li></ul><p>Советы для эффективного обучения: практикуйтесь на реальных данных (импортируйте CSV-файл в SQLite), сразу изучайте индексы — они кардинально влияют на производительность. Читайте наш материал об <a href="https://tproger.ru/articles/sql-indeksy-za-10-minut--kak-uskorit-zaprosy-v-baze-dannyh">SQL-индексах за 10 минут</a> и <a href="https://tproger.ru/articles/optimizaciya-sql-zaprosov--10-sovetov-dlya-nachinayushhih">10 советов по оптимизации запросов</a>.</p><h2>Выводы</h2><p>SQL — фундаментальный навык для любого, кто работает с данными. За полвека существования язык не только не устарел, но и стал ещё более востребованным: облачные хранилища BigQuery и Redshift, аналитические инструменты, современные ORM — всё это работает поверх SQL или совместимо с ним.</p><p>Что делать дальше:</p><ol><li>Установите PostgreSQL или откройте SQLiteOnline.com и напишите первый SELECT.</li><li>Пройдите интерактивный курс на SQLBolt.com — займёт 3–5 часов.</li><li>Попрактикуйтесь на реальных данных: загрузите любой CSV-датасет с Kaggle.</li><li>Изучите индексы — это самый быстрый способ ускорить запросы.</li><li>Посмотрите нашу дорожную карту SQL и двигайтесь по ней системно.</li></ol><p>SQL знают и продолжают учить потому, что он действительно работает. Сотни миллионов строк в банках, маркетплейсах и SaaS-сервисах каждый день обрабатываются именно с помощью SQL-запросов. Это инвестиция в навык, который окупится независимо от выбранного стека.</p>]]></content:encoded>
    </item>
    <item>
      <title>Вышел Bun 1.3: full-stack рантайм, поддержка Redis и новый SQL API. Разобрались, что еще нового</title>
      <link>https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo</link>
      <comments>https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo</guid>
      <description><![CDATA[<p>Bun 1.3 стал full-stack рантаймом с Redis, SQL API, поддержкой MySQL и PostgreSQL, новым тест-раннером и ускорением сборки до 2,5 раз</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo">Вышел Bun 1.3: full-stack рантайм, поддержка Redis и новый SQL API. Разобрались, что еще нового</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 13 Oct 2025 04:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Команда <b>Oven</b> <a href="https://bun.com/blog/bun-v1.3">представила</a> <b>Bun 1.3</b> — крупнейший релиз в истории JavaScript-рантайма.</p><p>Теперь Bun официально позиционируется как <b>full-stack платформа</b> для фронтенда и бэкенда. И она объединяет сервер, сборщик, менеджер пакетов вместе с тест-раннером в одном инструменте.</p><p>В новую версию добавлены десятки ключевых функций: встроенные клиенты для <b>Redis</b>, <b>MySQL</b>, <b>PostgreSQL</b> и <b>SQLite</b>, единый <b>SQL API</b>, улучшенные <b>WebSocket-модули</b>, переработанный <b>тест-раннер</b> и поддержка <b>VSCode Test Explorer</b>.</p><h2>Full-stack по-умному</h2><p>Главное новшество — режим <b>full-stack Bun.serve()</b> с поддержкой роутинга, cookies и WebSockets.</p><p>Теперь фронтенд и бэкенд можно запускать в одном процессе без проблем с CORS, а приложение собрать в <b>единый исполняемый файл</b> с помощью bun build --compile.</p><p>Разработчики могут напрямую импортировать HTML, запускать React-приложения с хот-перезагрузкой и собирать проект одной командой bun init --react. По данным команды, скомпилированные React-приложения в Bun работают <b>до 1,8 раза быстрее, чем через nginx</b>.</p><h2>Новый SQL и встроенный Redis</h2><p>Bun 1.3 представил унифицированный <b>Bun.SQL API</b> — теперь один и тот же код работает с MySQL, PostgreSQL, SQLite и MariaDB. Добавлен хелпер sql.array() для работы с массивами в PostgreSQL, улучшена поддержка JSON и Unix-сокетов.</p><p>Кроме того, в рантайм встроен <b>Redis-клиент</b>, который поддерживает 66 команд, автоматическое переподключение, очереди сообщений и Pub/Sub. По данным разработчиков, он <b>значительно быстрее ioredis</b>, а поддержка кластеров и Lua-скриптов появится в будущих релизах.</p><h2>Новые возможности</h2><p>Среди прочих улучшений — <b>Zstandard-сжатие</b>, нативная поддержка <b>YAML</b>, API для безопасного хранения секретов (<b>Bun.secrets</b>), и серьезный прирост производительности: операции с криптографией ускорены <b>до 400х</b>, установка пакетов — <b>до 2,5х</b>.</p><p>Также обновлен менеджер пакетов с <b>интерактивным bun update</b>, изолированными установками и API для проверки безопасности зависимостей.</p><h2>Почему это важно</h2><p>Bun 1.3 превращает экспериментальный рантайм в <b>полноценную платформу для веб-разработки</b>, способную заменить Node.js, Vite и Redis-CLI одновременно.</p><p>Разработчики называют релиз «началом новой эпохи», цель которой — сделать Bun лучшим способом писать и развертывать JavaScript-приложения.</p>]]></content:encoded>
    </item>
    <item>
      <title>Куда двигаться после изучения Django: советы для Python-разработчиков</title>
      <link>https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299</link>
      <comments>https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгения Епихина]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299</guid>
      <description><![CDATA[<p>В статье разбираемся, почему Django — далеко не финиш в карьере, и в каких направлениях можно двигаться Python-разработчику.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299">Куда двигаться после изучения Django: советы для Python-разработчиков</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Raspberry Pi]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Асинхронное программирование]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[NoSQL]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Neo4j]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 12 Aug 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Django — это веб-фреймворк на языке Python, который позволяет быстро создавать сложные веб-приложения. Он включает в себя готовые компоненты для работы с базами данных, маршрутизацией URL, обработкой форм, аутентификацией пользователей и админ-панелями, что значительно ускоряет разработку и упрощает поддержку проектов.</p><p>Владение Django — это старт, а не финиш. Чтобы оставаться востребованным, нужно постоянно расширять знания и навыки. В этой статье разберем пути и направления для улучшения своих компетенций.</p><h2>Почему владение Django — не предел для разработчика</h2><h2>Особенности Django</h2><p>Django используют для разработки веб-приложений разной сложности: при работе с большими базами данных, для создания сервисов, способных обслуживать большое количество пользователей. На нём создают соцсети, новостные сайты, веб-версии приложений, онлайн-магазины.</p><p>Основные плюсы:</p><ul><li><b>Полноценный стек</b>: ORM для работы с базой, мощная система маршрутизации URL, шаблоны для рендеринга, встроенная админка, формы, система аутентификации и авторизации.</li><li><b>Архитектура MTV (Model-Template-View)</b>: похожа на классический MVC, но с особенностями, которые упрощают разделение логики, представления и данных.</li><li><b>Безопасность</b>: Django автоматически защищает от CSRF, XSS, SQL-инъекций и других распространенных атак. Не нужно писать много дополнительного кода.</li><li><b>Активное сообщество и экосистема</b>: тысячи сторонних пакетов, расширений и готовых решений.</li><li><b>Поддержка нескольких баз данны</b>х: PostgreSQL, MySQL, SQLite, Oracle и др.</li></ul><p>Ограничения:</p><ul><li><b>Синхронная природа Django</b>.</li><li><b>Монолитность</b>: архитектура фреймворка ориентирована на создание крупных приложений, но в микросервисах может быть избыточна.</li><li><b>Ограниченная гибкость ORM</b>: нестандартные SQL-запросы иногда сложно выразить средствами ORM, приходится использовать raw SQL или сторонние библиотеки для запросов.</li><li><b>Строгие правила организации кода</b>: требуют дисциплины и могут ограничивать свободу в архитектурных решениях.</li><li><b>Недостаточная производительность</b>: уступает лёгким асинхронным фреймворкам (например, FastAPI), особенно под высокими нагрузками. Но для большинства проектов пока это не критично.</li></ul><h2>В каком направлении двигаться после изучения Django</h2><blockquote>Задача — создавать продукт, который будет нужен конечному потребителю.</blockquote><h3>Первое направление для развития — расширить инструментарий для решения разных задач в веб-разработке</h3><p>Возможные пути:</p><ul><li>Изучить другие веб-фреймворки (Flask, FastAPI)</li><li>Углубиться в асинхронное программирование (asyncio, aiohttp)</li><li>Работать с API и микросервисами</li></ul><h4>Flask и FastAPI</h4><p>Flask — минималистичный микрофреймворк, даёт полную свободу в выборе компонентов. Используют для небольших приложений и микросервисов.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-12/bbe7c040-14de-426d-9a10-c556f7319bee.png" alt="" /><figcaption>Пример простой команды на Flask</figcaption></figure><p>FastAPI — современный асинхронный фреймворк, ориентирован на создание высокопроизводительных API. Поддерживает стандарт OpenAPI и автоматическую генерацию документации. Он быстрее Flask и Django благодаря asyncio и Pydantic.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-12/33a27277-5136-4a03-8af2-f436db42fa99.png" alt="" /><figcaption>Пример простого API на FastAPI</figcaption></figure><h4>Асинхронное программирование</h4><p>Веб-разработка всё активнее использует асинхронные технологии. Django не всегда справляется с задачами высокой конкурентной нагрузки.</p><p>Поэтому изучение asyncio — стандартной библиотеки Python для асинхронного программирования — откроет перед вами новые возможности. Вместе с aiohttp или тем же FastAPI вы сможете создавать приложения, которые обрабатывают тысячи одновременных соединений. Это особенно важно для real-time сервисов, чат-приложений и систем с интенсивным обменом данными.</p><h3>Второе направление — расширить навыки в смежных областях</h3><p>Можно пойти по пути расширения компетенций за пределы основной специализации. Важно не только уметь писать код, но и понимать, как приложения разворачиваются и работают в продакшене. Знание DevOps-практик помогает наладить эффективное взаимодействие между разработкой и эксплуатацией.</p><h4>Изучение DevOps и контейнеризации</h4><p>Контейнеры позволяют запускать приложения в изолированной среде, это упрощает настройку и развертывание. Например, Docker помогает упаковать приложение с зависимостями в один контейнер, а Kubernetes — управлять такими контейнерами в продакшене. Знание этих технологий улучшит взаимодействие с операционной командой и ускорит выпуск новых версий приложений.</p><h4>CI/CD и автоматизация процессов</h4><p>Непрерывная интеграция (Continuous Integration) и непрерывное развертывание (Continuous Deployment) — ключевые практики современной разработки ПО. Они позволяют автоматизировать сборку, тестирование и доставку приложений, масштабировать процессы.</p><p>Инструменты CI/CD (например, Jenkins, GitLab CI/CD, GitHub Actions) помогают настроить автоматические пайплайны, которые обеспечивают быструю обратную связь и минимизируют человеческий фактор в релизах. Автоматизация процессов снижает количество ошибок и позволяет сосредоточиться на разработке новых функций.</p><p>Настройка непрерывной интеграции и доставки (Continuous Integration / Continuous Delivery) снижает поток ошибок при релизах и экономит время. Пример: GitHub Actions для автоматического запуска тестов и сборки проекта при каждом коммите.</p><h4>Больше знаний в области баз данных</h4><p>Помимо классических реляционных баз данных (PostgreSQL, MySQL), современные приложения часто используют NoSQL для специфичных задач. MongoDB, Redis, Cassandra обеспечивают гибкость в хранении данных, горизонтальное масштабирование и высокую производительность при работе с большими объемами информации.</p><p>Графовые базы данных (Neo4j, ArangoDB) предназначены для эффективного хранения и анализа связей между объектами, что важно для социальных сетей, рекомендательных систем и других приложений с богатой структурой.</p><p>Так, Redis хорошо подходит для кэширования данных, а Neo4j — для сложных связей между объектами.</p><h3>Третье направление — переход к другим аспектам Python-разработки</h3><p>Рассмотрим четыре варианта карьерного развития для Python-программиста: Data Science и машинное обучение, автоматизация бизнес-процессов, разработка десктопных приложений и встраиваемые системы (IoT).</p><p>Почему стоит попробовать?</p><ul><li>Высокий спрос на специалистов. Они востребованы в банках и инвестиционных компаниях, в сфере медицины и биотехнологии, в консалтинге,  автомобильной промышленности и т.д..</li><li>Широкий набор библиотек: pandas, NumPy, scikit-learn, TensorFlow, PyTorch.</li><li>Возможность работать с реальными задачами: от бизнеса до науки.</li></ul><h4>Автоматизация и скрипты для бизнеса</h4><p>Python часто используется для автоматизации рутинных задач: парсинга данных, обработки файлов, интеграции систем, генерации отчетов. Создание скриптов для автоматизации бизнес-процессов помогает повысить эффективность работы и снизить количество ошибок.</p><p>Знание таких библиотек, как openpyxl (работа с Excel), requests (HTTP-запросы), BeautifulSoup и Scrapy (парсинг веб-страниц), а также умение писать скрипты под конкретные задачи, делают разработчика ценным специалистом в корпоративной среде.</p><p>Примеры задач:</p><ul><li>Автоматическая загрузка данных из Excel и их преобразование</li><li>Скрипты для отправки email-рассылок</li><li>Интеграция с CRM и другими сервисами через API</li></ul><h4>Разработка десктопных приложений (PyQt, Kivy)</h4><p>Хотя сейчас популярность уходит к вебу и мобильным платформам, десктопные приложения на Python востребованы в таких сферах: инструменты для анализа, редакторы, утилиты.</p><p>Инструменты для создания:</p><ul><li>PyQt — мощный фреймворк для создания кроссплатформенных GUI.</li><li>Kivy — библиотека для разработки приложений с поддержкой сенсорных экранов.</li></ul><p>Этот путь подходит тем, кто хочет создавать удобные инструменты с графическим интерфейсом для пользователей на Windows, macOS или Linux.</p><h4>Встраиваемые системы и IoT</h4><p>В области IoT и встроенных систем Python набирает популярность благодаря легкости освоения и поддержке на маломощных устройствах. Помогают в этом  платформы по типу Raspberry Pi и MicroPython.</p><p>Изучение этого направления открывает возможности работы с аппаратным обеспечением, созданием прототипов и внедрением инновационных решений в промышленности и бытовой технике.</p><p>Например, с помощью Python на Raspberry Pi можно  разрабатывать датчики для мониторинга состояния оборудования на производстве и разрабатывать прототипы носимых устройств для сбора данных о здоровье.</p><blockquote>Если рассматривать профессию “Python-разработчик на Django”, то сразу получится сужение до конкретной библиотеки на конкретном языке. Если же в резюме у специалиста стоит, что он “разработчик Python”, возможностей сильно больше. Если написать про себя “разработчик”, будет не понятно, разработчик чего. Но изменив резюме на “DevOps инженера”, становится понятен карьерный трек.</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>5 VPS-хостингов в 2025, которые держат нагрузку: кейсы, стоимость, метрики</title>
      <link>https://tproger.ru/articles/5-vps-hostingov-v-2025--kotorye-derzhat-nagruzku--kejsy--stoimost--metriki</link>
      <comments>https://tproger.ru/articles/5-vps-hostingov-v-2025--kotorye-derzhat-nagruzku--kejsy--stoimost--metriki?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Валерия Турчак]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/5-vps-hostingov-v-2025--kotorye-derzhat-nagruzku--kejsy--stoimost--metriki</guid>
      <description><![CDATA[<p>Сравниваем 5 VPS-провайдеров, которые стабильно работают под нагрузкой в 2025 году. Разбираем стоимость, примеры использования, производительность и uptime. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/5-vps-hostingov-v-2025--kotorye-derzhat-nagruzku--kejsy--stoimost--metriki">5 VPS-хостингов в 2025, которые держат нагрузку: кейсы, стоимость, метрики</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Быстрый старт]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[ВКонтакте]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[VPN]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[Windows Server]]></category>
      <category><![CDATA[Образование]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Техподдержка]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[AMD]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 05 Aug 2025 06:10:17 GMT</pubDate>
      <content:encoded><![CDATA[<p>В 2025 году выбирать VPS по принципу дешево и сердито уже не работает. Любой рабочий или MVP-проект — от API для мобильного приложения до интернет-магазина  сталкивается с пиками нагрузки, которые нужно выдержать. Ошибки на старте обходятся дороже простоя в продакшне.</p><p>Собрали пять VPS-хостингов, которые показывают, как должны выглядеть выжившие серверы под нагрузкой: современное железо, каналы без счётчиков трафика, живая поддержка инженеров и опыт клиентов. Ниже — конфигурации, цены и метрики, чтобы вы подобрали сервер под свой сценарий.</p><h2>1. ИХЦ (Интернет ХостингЦентр): конфигурации под нагрузку с NVMe, CPU до 5 ГГц и трафиком без ограничений</h2><p>Один из самых гибких по конфигурациям хостеров в обзоре. Работает с 2009 года. Поддерживает разные типы виртуализации (KVM и Virtuozzo), предлагает линейки с SSD и NVMe, российские и европейские площадки, разные уровни мощности — от базовых до высоконагруженных.</p><h3>Линейки VPS и конфигурации</h3><ol><li>ssdVPS — базовая линейка для России. Позволяет собирать конфигурации от 1 до 32 ГБ оперативной памяти, от 1 до 10 виртуальных CPU и от 20 до 300 ГБ SSD-диска.</li><li>NVMe/ — линейка на базе KVM с более высокой производительностью ввода-вывода. Доступны конфигурации от 1 до 24 ГБ RAM, от 1 до 12 vCPU, SSD от 15 до 300 ГБ.</li><li>EU-NVMe/ — аналог NVMe-линейки, но размещённый в Амстердаме. Конфигурации расширены: от 1 до 64 ГБ оперативной памяти, от 1 до 18 CPU, от 15 до 1000 ГБ SSD, скорость порта — от 200 до 500 Мбит/с.</li><li>VPS 5 ГГц — отдельная линейка на KVM, ориентированная на проекты с высокой частотной нагрузкой, до 5 ГГц на ядро, порт до 1000 Мбит/с.</li></ol><p>VPS Windows — выделенная категория для задач на Windows.</p><h3>Особенности и инфраструктура</h3><p>В <a href="https://www.ihc.ru/vps.html">ИХЦ</a> можно выбрать между двумя видами виртуализации: <b>KVM</b> и <b>Virtuozzo</b>. Виртуализация KVM подходит для задач, где нужна изоляция ресурсов, стабильность под нагрузкой и совместимость с Linux и Windows. Virtuozzo — более экономный вариант с быстрой настройкой, но с возможной перераспределённой нагрузкой между соседними VPS.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/d8f9548f-7bd8-4eef-a4aa-6d50b0e424a2.png" alt="" /><figcaption>Дата-центры провайдера есть в Москве и Амстердаме.</figcaption></figure><p>Связь с поддержкой доступна через тикеты, онлайн-чат на сайте, телеграм-бота, телефон и сообщения ВКонтакте. Поддержка работает 24/7. На всех тарифах включена базовая <b>DDoS-защита</b>.</p><h3>Примеры использования VPS от IHC</h3><p>Компания предоставляет конкретные кейсы. Примеры:</p><ul><li>Проект 1: VPS NVMe/24 (24 ГБ RAM, ~200 ГБ SSD) используется под бэкенд iOS-приложения. Стек: nginx, PHP, MySQL. Нагрузка: 12 000 уникальных пользователей в сутки. Утилизация CPU — 25%.</li><li>Проект 2: VPS NVMe/12 (12 ГБ RAM, ~120 ГБ SSD) для развлекательного сайта. Стек: nginx, Docker, Node.js. Нагрузка: 7 000 уникальных пользователей в сутки, загрузка CPU — около 20%.</li></ul><p>Серверы стабильно держат среднюю и высокую нагрузку — даже с трафиком в 10–12 тысяч пользователей в сутки остаётся запас по ресурсам.</p><h3>Дополнительные опции</h3><p>ИХЦ предлагает <b>тестовый период в 3 дня</b>, <b>безлимитный трафик</b>, <b>бесплатный первый месяц ispmanager 6</b> в подарок, а также предустановку панелей управления (ispmanager, FastPanel) или VPN-шаблонов по выбору при заказе. Также доступны бэкапы, SLA и автоснапшоты.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/e5730a1c-375b-4b91-a238-6a52a51df67a.png" alt="" /></figure><h3>Цены</h3><p>Что касается ценовой политики, стоимость VPS в России (линейка «ssdVPS») начинается <b>от 380 руб/мес</b> или 3800 руб/год (12 месяцев по цене 10). Европейские VPS («EU-NVMe/») и VPS на KVM («NVMe/») стартуют <b>от 440 руб/мес</b> или 4400 руб/год, а каждый дополнительный гигабайт памяти стоит 6 рублей.</p><h2>2. FirstVDS: мощные VDS на AMD EPYC и Ryzen</h2><p><a href="https://firstvds.ru/">FirstVDS</a> — хостинг-провайдер с опытом на рынке более 20 лет. Предлагают VPS и VDS с виртуализацией KVM для проектов любого размера. Все серверы работают на современном оборудовании. Трижды победитель в номинации «Хостер года» Национальной премии «ЦОДы.РФ».</p><p>Есть VPS для разных сценариев нагрузки — от стандартных сайтов до тяжёлых веб-приложений и проектов с высокими требованиями к CPU и отказоустойчивости. Отдельные решения для Битрикс, установка ОС семейства Linux, FreeBSD и Windows Server.</p><h3>Линейки VPS: от базовой мощности до кластера Ceph</h3><p>FirstVDS предлагает три основные линейки, которые отличаются архитектурой и назначением:</p><ol><li>VDS Форсаж — гибкая конфигурация сервера на базе AMD EPYC, до 128 ядер (до 3,7 ГГц), до 512 Гб оперативной памяти и до 4 000 Гб быстрого NVMe-накопителя. Локации Москва и Амстердам. Стартовая стоимость такой конфигурации составляет от 749 руб/мес.</li><li>Для нагруженных проектов — CPU.Турбо — гибкая конфигурация сервера на базе AMD Ryzen с частотой до 5,7 ГГц, DDR5 и с быстрыми NVMe-накопителями. Идеально для Битрикс. Локация Москва. Начальная цена CPU.Турбо — от 624 руб/мес. При покупке лицензии Битрикс (1С-Битрикс: Управление сайтом или Битрикс24) есть дополнительная скидка 30% на 3 месяца аренды этого тарифа.</li><li>Отказоустойчивый VDS Атлант — гибкая конфигурация сервера на базе AMD EPYC — до 192 ядер (до 3,5 ГГц), до 768 Гб оперативной памяти и до 8 Тб быстрого NVMe-накопителя. Репликация данных между узлами кластера Ceph и дублирование сетевого оборудования. Локация Москва. Его стартовая стоимость от 1619 руб/мес, при этом бесплатные автобэкапы уже включены.</li></ol><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/3490237d-3e99-49c5-9d90-10e3849765ed.png" alt="" /></figure><p>Компания использует два центра обработки данных в <b>Москве</b>: <b>IXcellerate (уровень Tier III)</b> и Web DC. Для тарифа Форсаж и готовых тарифов также доступен ЦОД <b>euNetworks (уровень Tier III) в Амстердаме</b>.</p><h3>Сетевые возможности, трафик и безопасность</h3><p>В стоимость каждого сервера входит бесплатный выделенный IP-адрес. Клиенты могут выбрать между 100 Мбит/с с безлимитным трафиком или портом 1 Гбит/с с включёнными 32 Тб трафика.</p><p>Защита от DDoS-атак и система безопасности BitNinja для сервера и сайта доступны как подключаемые опции. Также предоставляются объектное хранилище S3, автобэкапы и Кибер-бэкап. Для безопасности коммуникаций используются SSL-сертификаты GlobalSign.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/7d36ac0d-4832-402b-b0b0-9d7955963916.png" alt="" /></figure><h3>Управление, ПО и поддержка</h3><p>При заказе сервера клиент получает лицензию ispmanager 6  lite: первый месяц панель предоставляется бесплатно, дальше оплачивается по тарифу самой панели. Предлагается гибкий выбор операционных систем, включая Linux, FreeBSD и Windows Server. Под разовые задачи доступны готовые рецепты установки — от Битрикс и GitLab до TeamSpeak, LAMP‑стека и других популярных наборов ПО.</p><p>Для установки и решения любых вопросов — доступна живая круглосуточная техническая поддержка 24/7 через чат на сайте, в личном кабинете и по телефону, без использования чат-ботов. Для самостоятельного решения вопросов предусмотрена обширная база знаний.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/7fc897fc-5d2d-4f28-9047-834a8b0202b1.png" alt="" /></figure><h3>Клиентские бонусы и программы</h3><p>Есть тестовый период до 3 дней. Регулярно проводятся акции и предоставляются скидки, в том числе на тарифы для нагруженных проектов.</p><p>1) При переходе от другого хостера FirstVDS бесплатно переносит до 10 сайтов. Дополнительно предоставляется скидка 40% на первый месяц аренды VPS при оплате сервера на 1, 3 или 6 месяцев, либо 3 месяца бесплатной аренды VPS при оплате на год.</p><p>2) Клиенты с возрастом аккаунта от 5 лет получают постоянную скидку на аренду VPS, начиная от 5% и увеличиваясь ежегодно до 20%.</p><p>3) Действует реферальная программа, по которой партнёр получает 10% от расходов привлечённых клиентов, а привлечённый пользователь — скидку 25% на первый месяц аренды VPS.</p><p>4) Стоимость продления домена у FirstVDS равна актуальной стоимости его регистрации.</p><h2>3. InCloud: VPS‑площадки для бизнеса, где важен SLA</h2><p><a href="https://incloud.ru/">InCloud</a> продаёт виртуальные серверы, работающие в отказоустойчивом кластере на базе enterprise хранилищ NetApp и HPE 3PAR. Позиционируется как решение для 1С, малого/среднего бизнеса и аутсорс компаний, которым нужны предсказуемые ресурсы и техподдержка профессиональных инженеров, а не чат‑ботов.</p><h3>Тарифные планы и ценообразование</h3><p>InCloud предлагает две основные линейки тарифов:</p><ol><li>Стандартный тариф: внутри процессоры Intel Xeon 2600v4 2ГГц и оперативная память DDR4 2400 МГц.Стоимость: 1 CPU – 200 рублей, 1 Гб RAM – 200 рублей.</li><li>Производительный тариф: использует процессоры AMD EPYC до 3.8 ГГц и оперативной памяти DDR5 4800 МГц. Стоимость: 1 CPU – 250 рублей, 1 Гб RAM – 250 рублей.</li></ol><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/c484688e-fd3f-48ca-b743-616c21699ac4.png" alt="" /></figure><p><b>Стоимость дискового пространства</b>: SATA диски: <b>3 рубля за 1 Гб</b>. SSD и NVMe диски: <b>13 рублей за 1 Гб</b>.</p><h3>Архитектура и поддержка</h3><p>Теперь про то, что упрощает жизнь и добавляет надежности нашим развернутым сервисам:</p><ul><li>Ежедневные бэкапы: данные ваших серверов будут копироваться каждый день, и храниться они могут до 30 дней.</li><li>Удобная панель управления: через нее можно делать снапшоты  и клонировать серверы. Для разработчиков это просто золото – быстро накатить тестовую среду, попробовать новую фичу, а потом откатиться или создать идентичные рабочие среды.</li><li>SLA-договор: есть возможность заключить SLA-договор, чтобы получить гарантированный уровень доступности услуг.</li><li>Новейшие мощные серверы — на базе AMD EPYC 4 поколения.</li></ul><p>Одна из фишек – это возможность напрямую проконсультироваться с сертифицированными инженерами InCloud по сложным проектам.</p><h3>А что с клиентскими кейсами</h3><ol><li><b>Кейс Vamkamin</b>: производственная компания, которая ускорила работу своей системы 1С и сократила IT-расходы на 35%. У них была проблема с медленной работой 1С при одновременном доступе бухгалтерии, склада и отдела продаж, а также с частыми простоями на локальных серверах. InCloud предложил перенести все сервисы в облако, используя серверы на базе AMD EPYC 9554, что обеспечило прирост производительности более 40% по сравнению с предыдущими решениями. Также были внедрены гибкое масштабирование ресурсов и ежедневное резервное копирование.</li><li><b>Кейс Веб-студии 100UP</b>: компания занимается разработкой и поддержкой сайтов для крупных торговых сетей и e-commerce проектов. 100UP переехала к облачному провайдеру InCloud, выбрав тарифы на базе AMD EPYC 9554 с высокой тактовой частотой и большим количеством ядер. Благодаря разнообразию тарифов команда легко распределила проекты по нужным по производительности виртуальным серверам. После переезда 100UP смогла сократить время отклика клиентских сайтов в среднем на 45%, обеспечить бесперебойную работу даже в периоды высокой сезонной нагрузки, ускорить запуск новых проектов, фокусироваться на разработке и маркетинге и улучшить качество предоставляемых услуг.</li></ol><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/c0b63a9f-bb39-4b44-9363-45cefd4c2f62.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/9f98fda8-0b7a-408a-9a82-00f063ee0d88.png" alt="" /></figure><h2>4. SmartApe: быстрые VPS на NVMe‑SSD</h2><p><a href="https://www.smartape.ru/ssd-vps">SmartApe</a> подойдет проектам, где дисковая подсистема и CPU работают без простоя: интернет‑магазины, порталы с большим количеством контента, внутренние корпоративные системы, высоконагруженные API. Если нужен быстрый старт — сервер создаётся за одну‑две минуты; если понадобится масштабирование, тариф можно увеличить без миграции.</p><h3>Преимущества этих VPS</h3><p>Используются современные серверные NVMe SSD диски в RAID массиве, которые в 600 раз быстрее обычных HDD. Скорость чтения достигает 8000 Мбайт/с, а записи — 2000 Мбайт/с.</p><p>Серверы работают на мощных процессорах Intel Xeon Gold или AMD EPYC (до 3.7 ГГц) и быстрой памятью DDR4. Используется полноценная виртуализация KVM с выделенными ресурсами для гарантии их предоставление. Дата-центры уровня TIER-III и TIER-IV обеспечивают Uptime 99.982%. Данные хранятся в хранилище RAID-10.</p><p>Дополнительно клиенты получают полный root-доступ (по SSH для Linux и RDP для Windows), возможность установки любых операционных систем (более 20, включая Ubuntu, CentOS, Debian, Windows Server) и ПО, а также полную изоляцию от других клиентов.</p><h3>Удобство и поддержка</h3><ul><li>Бесплатная панель управления (Hestia) или платная ISPmanager для простого управления сервером.</li><li>Бесплатное базовое администрирование и помощь в переносе сайтов.</li><li>Круглосуточная квалифицированная поддержка 24/7.</li><li>Бесплатный тестовый период 10 дней без оплаты и ввода карты.</li><li>Защита от DDoS-атак включена в стоимость.</li><li>Выделенный внешний IP-адрес (возможность купить до 10 IP).</li></ul><p>Перед покупкой дают десять дней теста без привязки карты; если сервис не подойдёт, в течение тридцати дней можно вернуть деньги за неиспользованный период.</p><h4>Пример использования: интернет‑магазин</h4><p>VPS c 2 vCPU, 4 ГБ RAM, 80 ГБ SSD и портом 100 Мбит/с; при обычном трафике сайт обслуживает 300–500 уникальных посетителей в день, одновременно на страницах бывает 10–20 человек, а в пиковую распродажу до 50; средняя нагрузка 5–10 запросов в секунду, короткими всплесками до 20; заявленный аптайм 99,982 %, реальные замеры отклика после кэширования — 200–300 мс; счёт за такой сервер выходит около 1 300 рублей в месяц.</p><h4>Пример использования: API на Node.js</h4><p>4 vCPU, 8 ГБ RAM, 160 ГБ NVMe и канал 200 Мбит/с; сервис стабильно обрабатывает 50–100 запросов в секунду, на пике достигает 200, одновременно подключены 500–1 000 клиентов, максимум 2 500; трафик близок к 200 ГБ в месяц; при том же аптайме 99,982 % средняя задержка ответа укладывается в 50–100 мс; ежемесячная стоимость в зависимости от опций колеблется в диапазоне 2 600–3 000 рублей.</p><p>SmartApe имеет смысл брать, когда дисковая скорость и гарантированные ресурсы важнее высокого GUI и почасовой тарификации, для расчёта стоимости есть калькулятор конфигураций на сайте и оперативная техподдержка.</p><h2>5. PSB Hosting: что даёт их VPS‑платформа</h2><p><a href="https://psb.hosting/vps">PSB Hosting</a> продвигает VPS-хостинг как решение для сайтов, приложений и SaaS-сервисов, которым нужна предсказуемая мощность и высокий SLA. Провайдер делает упор на новое оборудование, пропускную способность без ограничений и инфраструктуру уровня Tier III+.</p><h3>Локации и тарификация</h3><p>Серверы разворачиваются в четырёх точках: Нидерланды, США, Германия и Финляндия. Для каждой площадки доступен одинаковый конструктор конфигураций. Базовый план NL‑100, который включает 1 vCPU, 2 ГБ RAM и 30 ГБ SSD, стоит 6 долларов в месяц. Линейка поднимается ступенчато:</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/62dfc578-ede9-4533-bfb8-bca1a1a26688.png" alt="" /></figure><p>Слайдеры позволяют довести параметры до 32 ядер, 64 ГБ RAM и 510 ГБ SSD; верхняя планка оплаты — 220 $ в месяц.</p><p>Трафик безлимитный на любых конфигурациях — дополнительной оплаты за гигабайты нет.</p><h3>Аппаратная платформа, ОС и предустановки</h3><p>В хост-узлах применяются процессоры последних линеек AMD и Intel. Оперативная память — DDR5, что снижает задержки при обращении к ОЗУ. Дисковая подсистема полностью на NVMe, объединена в RAID 10: чтение и запись выше, чем у классических SSD, а отказ одного накопителя не выводит хранилище из строя. К каждому VPS подключён выделенный канал с пропускной способностью до 10 Гбит/с.</p><p>Сервер можно поднять сразу с Windows Server, Ubuntu, Debian, CentOS или FreeBSD. Для быстрого старта доступны готовые образы: Bitrix, Django-стек, Docker, FastPanel, Hestia CP, Keitaro, LAMP, Node, OpenVPN, Outline, Portainer, Vesta CP и другие.</p><h3>Управление и поддержка</h3><p>Провайдер обещает круглосуточную техническую поддержку, резервные копии (бэкапы) и автоснапшоты. Для автоматизации предусмотрен API; в панели управления можно масштабировать ресурсы, перезагружать сервер и следить за статистикой.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/fabfe43d-7891-4129-8ad5-e87f45b087ef.png" alt="" /></figure><h2>Как выбрать VPS под свой проект</h2><p>Для сайта с пиковыми нагрузками подойдёт SmartApe, где дисковая подсистема на NVMe-SSD в RAID-10 обеспечивает скорость чтения до 8000 Мбайт/с и записи до 2000 Мбайт/с, а сайт на конфигурации с 2 vCPU, 4 ГБ RAM и 80 ГБ SSD выдерживает 300–500 уникальных посетителей в день с пиком до 50 одновременных пользователей и нагрузкой 5–10 запросов в секунду (короткими всплесками до 20).</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/bc98805d-7f7f-471d-a2a2-1df68139c637.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/204e63be-985f-449d-a37c-37ca9993d335.png" alt="" /></figure><p>Если проект включает высоконагруженный API, например, на Node.js, то оптимален SmartApe с конфигурацией 4 vCPU, 8 ГБ RAM и 160 ГБ NVMe, которая стабильно обрабатывает 50–100 запросов в секунду (пики до 200) при 500–1000 одновременных подключениях (максимум 2500) и трафике до 200 ГБ в месяц.</p><p>Для задач с 1С, где важна стабильность и сокращение IT-расходов, выбирайте InCloud на базе AMD EPYC 9554: в кейсе Vamkamin это ускорило работу системы на 40%, сократило расходы на 35% и минимизировало простои, с ежедневными бэкапами до 30 дней и SLA-договором.</p><p>Если нужен VPS для Битрикс с высокой частотой CPU, подойдёт FirstVDS на AMD Ryzen (CPU.Турбо) с частотой до 5,7 ГГц и DDR5: скидка 30% на 3 месяца при покупке лицензии Битрикс, плюс отказоустойчивость на кластере Ceph с репликацией данных.</p><p>Для веб-студий с разработкой и поддержкой сайтов для e-commerce, где требуется распределение проектов по производительности и бесперебойная работа в сезонные пики, подойдёт InCloud на AMD EPYC 9554: в кейсе 100UP это сократило время отклика на 45% и обеспечило стабильность под высокой нагрузкой.</p><p>Если проект ориентирован на международный трафик с предсказуемыми ресурсами и высоким SLA, выбирайте PSB Hosting с локациями в Нидерландах, США, Германии или Финляндии, безлимитным трафиком и каналом до 10 Гбит/с на DDR5 и NVMe в RAID 10.</p><p>Для бэкенда мобильного приложения с нагрузкой до 12 000 уникальных пользователей в сутки (утилизация CPU 25%) подойдёт ИХЦ на NVMe/24 с 24 ГБ RAM и ~200 ГБ SSD, стеком nginx, PHP, MySQL.</p><p>Если развлекательный сайт с более чем 5000 уникальных пользователей в сутки (загрузка CPU ~20%), то подходит ИХЦ на NVMe/12 с 12 ГБ RAM и ~120 ГБ SSD, стеком nginx, Docker, Node.js. Он обеспечит стабильность с безлимитным трафиком и DDoS-защитой.</p><p>Выбор сводится к трём вопросам: где ваши<br />пользователи, какую пиковую нагрузку вы ждёте и нужен ли формальный SLA.<br />Сформулируйте эти требования заранее — и любой из пяти хостингов закроет задачу<br />без проблем в продакшне. Добавить свои рекомендации VPS хостингов — вы всегда<br />можете в комментариях, желательно описывать короткие кейсы.</p>]]></content:encoded>
    </item>
    <item>
      <title>Что еще есть в терминале Linux: 7 команд, которые экономят кучу времени</title>
      <link>https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni</link>
      <comments>https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni</guid>
      <description><![CDATA[<p>Семь советов для ускорения работы в терминале Linux. Как быстро обработать файлы, отладить Bash-скрипт и редактировать длинные пути в Линукс.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni">Что еще есть в терминале Linux: 7 команд, которые экономят кучу времени</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 22 Jul 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>Сколько статей про «полезные команды Linux» вы уже прочитали?</b> Алиасы, history, базовые горячие клавиши — факты для джунов, которые опытным админам уже снятся. Если свободно пользуетесь grep и awk, создаете циклы, применяете регулярные выражения — эта статья для вас.</p><p>Рассказываем про 7 команд, влияющие на скорость работы в терминале. Вы узнаете:</p><ul><li>про встроенные bash-операции, которые заменяют пайплайны,</li><li>про способы работы с файловыми дескрипторами,</li><li>про wildcards, которые избавляют от сложных конструкций с find.</li></ul><p>Каждая команда в подборке решает конкретную проблему:</p><ul><li>массовая обработка файлов,</li><li>отладка скриптов,</li><li>работа с длинными путями.</li></ul><h2>1. Bash variable expansions</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/b5f2b475-b18e-49cb-a00c-9197ab87b9f4.jpg" alt="" /></figure><p>Вместо <i>basename</i>, <i>cut </i>для простых операций со строками можно использовать встроенные возможности Bash:</p><p><b>%</b> режет справа до первого совпадения, <b>%%</b> — до последнего. Символ <b>#</b> работает слева направо.</p><p>В реальной работе это помогает при массовой обработке файлов. Например, есть 1000 логов, и нужно каждый переименовать.</p><p>Если использовать <i>basename</i>, запустится 1000 отдельных процессов. <b>Variable expansions</b> работают без <i>fork/exec</i>, без задержек на создание процессов.</p><p>Bash variable expansions используют в циклах с файлами и при работе с массивами. Когда скрипт обрабатывает сотни файлов, разница в скорости становится заметной. Еще и код выглядит чище.</p><h2>2. Here-string (&lt;&lt;&lt;)</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/ef72e05d-6f80-49aa-842b-32c209d8b724.jpg" alt="" /></figure><p>Here-string упрощает передачу строковых данных в команды без создания временных файлов или использования echo с пайпом.</p><p>Реальная экономия времени проявляется при отладке и модификации скриптов. Например, когда SQL-запрос или конфигурация зашиты в <i>here-документ</i>. С <b>here-string </b>данные собраны в одном месте, легко редактируются и переиспользуются.</p><p>Работает не только с базами данных. Отправка в API, конфигурирование сетевых устройств через expect, передача команд в Docker — через &lt;&lt;&lt; код будет понятнее, а сопровождение проще.</p><h2>3. /proc/$$/fd</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/f314de69-9459-4ecb-ab62-2c7b5c7b54f3.jpg" alt="" /></figure><p>Каждый процесс имеет стандартные дескрипторы <b>0</b> (stdin), <b>1</b> (stdout), <b>2</b> (stderr), которые представлены как символические ссылки. Директория <b>/proc/$$/fd </b>предоставляет доступ к файловым дескрипторам текущего процесса:</p><p>Переменная <b>$$</b> содержит PID текущего процесса, поэтому /proc/$$/fd ведет к дескрипторам именно вашего шелла.</p><p>Практическое применение — отладка перенаправлений и работа с дескрипторами в сложных скриптах:</p><h2>4. Wildcards с диапазонами</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/08dbc2a0-5e2e-49a3-9486-a042a0480369.jpg" alt="" /></figure><p>Про <b>*</b> и <b>?</b> говорят чаще, чем про диапазоны в квадратных скобках. Такие маски используют реже, а зря — они решают массу задач по отбору файлов.</p><p>Wildcards автоматически раскрываются шеллом в список подходящих файлов — это их основная функция. Кавычки нужны только когда передаете символы [, ] как литеральные:</p><p>Экономия времени заметна при работе с логами, бэкапами и в скриптах автоматизации. Например, для архивации файлов с определенными номерами, очистки временных файлов с нужными паттернами.</p><h2>5. sudo !!</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/9434c945-925f-40b3-9062-994fce2091c6.jpg" alt="" /></figure><p>Набрали длинную команду, нажали Enter, получили «<b>Permission denied</b>». Рука на рефлексе тянется к стрелке вверх и Home, чтобы добавить sudo в начало.</p><p>Вот способ в разы быстрее:</p><p>Двойное восклицание <b>!!</b> — это ссылка на предыдущую команду целиком. Bash подставит всю строку со всеми аргументами и ключами. Кажется мелочью, но для админа, который 10 раз в день забывает sudo, это серьезная оптимизация.</p><p>Двойное восклицание универсально и работает не только с sudo:</p><ul><li><b>time !!</b> для замера времени выполнения,</li><li><b>nohup !! &amp;</b> для запуска в фоне,</li><li><b>strace !!</b> для отладки.</li></ul><p>Если между командой и sudo !! выполнялись другие команды, восклицание сработает для последней из них. Для поиска конкретной команды в истории используйте <b>!строка</b>.</p><h2>6. ^старое^новое</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/1888b625-8ae5-4d0e-a73d-25260ff7d893.jpg" alt="" /></figure><p>Основной способ исправления опечатки — стрелка вверх, поиск ошибки, исправление. Смотрите, как можно сделать это побыстрее:</p><p>Символ <b>^</b> ищет первое вхождение слова и заменяет его. Работает с последней командой.</p><p>Заменяется только первое вхождение. Если ошибочное слово встречается несколько раз, способ не сработает. В таких случаях придется использовать классическое редактирование или <i>history expansion</i>.</p><h2>7. Alt+.</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/4d1c03bb-66b2-4cb0-8c3e-ce80c3406ec5.jpg" alt="" /></figure><p>Создали файл с длинным именем — теперь его нужно отредактировать, переместить, изменить права. Каждый раз перепечатывать путь утомительно и чревато ошибками.</p><p>Комбинация <b>Alt+.</b> (Alt + точка) вставляет последний аргумент предыдущей команды в текущую позицию курсора. Повторное нажатие перебирает аргументы из более ранних команд.</p><p>Экономия времени проявляется при работе с файлами и директориями. Например: распаковали архив, теперь нужно зайти в созданную папку, затем посмотреть содержимое, потом изменить права. Вместо того, чтобы 3 раза печатать один путь, можно 3 раза нажать Alt+.</p><p>Еще этой комбинацией вставляются:</p><ul><li>имена пользователей,</li><li>IP-адреса,</li><li>названия сервисов,</li><li>параметры конфигурации.</li></ul><p>Alt + точка работает в большинстве шеллов. Привыкнув к ней, начинаешь использовать на автомате.</p><h2>Что запомнить</h2><ul><li><b>${filename%.*} </b>и встроенные операции со строками работают быстрее внешних утилит. % режет справа, # — слева. Полезно при работе с циклами для массовой обработки файлов.</li><li><b>&lt;&lt;&lt;</b> — here-string удобен для передачи коротких строковых данных в команды. С многострочными данными лучше использовать here-document или переменные.</li><li><b>/proc/$$/fd</b> — доступ к файловым дескрипторам текущего процесса. Ускоряет отладку перенаправлений и работу с дескрипторами.</li><li><b>file[1-5] и [^b]* </b>— диапазоны в wildcards для точного отбора файлов. Кавычки нужны только для передачи литеральных символов.</li><li><b>sudo !!</b> — повторяет последнюю команду с sudo. Также работает с time !!, nohup !! &amp;. Если между нужной командой и !! выполнялись другие операции, используйте !строка для поиска конкретной команды в истории.</li><li><b>^старое^новое</b> — заменяет первое вхождение в предыдущей команде. Работает только с последней командой и заменяет первое совпадение.</li><li><b>Alt+. </b>— вставляет последний аргумент предыдущей команды. Повторное нажатие перебирает аргументы из истории команд. Экономит время при работе с длинными путями.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Выбираем российский хостинг в 2025: подборка на любой запрос</title>
      <link>https://tproger.ru/articles/vybiraem-rossijskij-hosting-v-2025--podborka-na-lyuboj-zapros</link>
      <comments>https://tproger.ru/articles/vybiraem-rossijskij-hosting-v-2025--podborka-na-lyuboj-zapros?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/vybiraem-rossijskij-hosting-v-2025--podborka-na-lyuboj-zapros</guid>
      <description><![CDATA[<p>В этом материале — семь проверенных российских хостингов для разных задач: от стартапа до корпоративного проекта. Каждый прошел тестирование на аптайм (время бесперебойной работы), безопасность и доступность поддержки.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/vybiraem-rossijskij-hosting-v-2025--podborka-na-lyuboj-zapros">Выбираем российский хостинг в 2025: подборка на любой запрос</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Ruby on Rails]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[Windows Server]]></category>
      <category><![CDATA[Техподдержка]]></category>
      <category><![CDATA[Россия]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[CMS]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 22 Jul 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В 2025 году российский хостинг переживает новый виток развития. После того как законодательство изменилось и добавились новые технологии, локальные провайдеры усилили инфраструктуру.</p><p>Теперь они предлагают решения, которые не хуже, а где-то даже и лучше международных аналогов и по надёжности, и по цене.</p><p>Посмотрим, кто из них есть в этом списке, и определим особенности хостингов для сайта.</p><h2>1. FirstVDS: профессиональные решения для любых проектов</h2><p><a href="https://firstvds.ru/">FirstVDS</a><a href="https://firstvds.ru/" rel="noopener noreferrer nofollow"></a> — хостинг-провайдер с опытом на рынке более 20 лет. Предлагают VPS и VDS с виртуализацией KVM для проектов любого размера. Все серверы работают на современном оборудовании. Трижды победитель в номинации «Хостер года» Национальной премии «ЦОДы.РФ».</p><p>Хостинг подойдет бизнесу любого масштаба: для любых сайтов — от визиток до высоконагруженных интернет-магазинов, для разработки и тестирования, для сервисов и других проектов. Отдельные решения для Битрикс, установка ОС семейства Linux и Windows Server.</p><h3>Особенности хостинга</h3><h4>Надёжность</h4><p>FirstVDS обеспечивает аптайм 99,97–99,99% в 2025 году, подтверждённый замерами (например, отклик из Москвы — 27 мс в апреле 2025). Серверы размещены в трёх дата-центрах уровня Tier III: два в Москве (IXcellerate и Web DC) и один в Амстердаме (euNetworks). Отказоустойчивый кластер Ceph гарантирует работу даже при сбоях точки или канала.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/80547603-f63a-4f2e-9bc1-332c9e061bf9.png" alt="" /></figure><h4>Инфраструктура</h4><p>Серверы работают на процессорах Intel Xeon и AMD EPYC (до 5,7 ГГц в линейке CPU.Турбо), с быстрыми NVMe-дисками объёмом до 8 ТБ и оперативной памятью DDR5 (до 768 ГБ в VDS Атлант). Это обеспечивает высокую производительность для ресурсоёмких задач, таких как Битрикс или высоконагруженные приложения.</p><h4>Гибкость</h4><p>Тарифы масштабируются: от базовых конфигураций (1 CPU, 1 ГБ RAM, 40 ГБ SSD) до мощных серверов (192 ядра, 768 ГБ RAM, 8 ТБ NVMe). Линейки:</p><ul><li>VDS Форсаж: AMD EPYC, до 128 ядер, 512 ГБ RAM, 4 ТБ NVMe, от 749 ₽/мес (Москва/Амстердам).</li><li>CPU.Турбо: AMD Ryzen до 5,7 ГГц, DDR5, от 624 ₽/мес (Москва).</li><li>VDS Атлант: отказоустойчивый, до 192 ядер, 8 ТБ NVMe, от 1619 ₽/мес (Москва).</li><li>VDS Storage: хранилище, от 704 ₽/мес (Москва).Горячее масштабирование (hot-resize) позволяет добавлять CPU, RAM или диск без перезагрузки.</li></ul><h4>Автоматизация</h4><p>Шаблоны для быстрого развёртывания: Django, Redmine, Tomcat, Teamspeak, Nextcloud, LAMP, LEMP, Forgejo Git, GitLab, Битрикс. Поддерживаются ОС Linux (Ubuntu, Alma, Debian, Rocky, CentOS, Oracle), FreeBSD, Windows Server. API и панель ispmanager 6 lite (бесплатно на месяц) упрощают управление.</p><h4>Безопасность</h4><p>Включена защита от DDoS-атак на сетевом уровне, BitNinja для защиты сервера и сайта, SSL-сертификаты GlobalSign. Доступны автобэкапы, снапшоты, Кибер-бэкап и объектное хранилище S3 для больших данных.</p><h4>Поддержка</h4><p>Круглосуточная поддержка 24/7 без чат-ботов, ответ до 15 минут через чат, личный кабинет или телефон. Бесплатно: помощь с активацией и первичной настройкой. Платно: установка ПО, администрирование. Экспертная линия для мониторинга и устранения сбоев.</p><h4>Бонусы</h4><ul><li>Тестовый период 3 дня.</li><li>Бесплатный перенос до 10 сайтов с другого хостера.</li><li>Скидки: 40% на первый месяц при оплате на 1/3/6 месяцев или 3 месяца бесплатно при оплате за год.</li><li>Лояльность: скидка 5–20% для клиентов от 5 лет.</li><li>Реферальная программа: 10% от расходов привлечённых клиентов для партнёра, 25% скидка для нового пользователя на первый месяц.</li><li>Домены: продление по цене регистрации.</li></ul><h3>Тарифы и условия</h3><p>Тестовый период 3 дня, после него подключаете один из основных тарифов:</p><ul><li>Линейка готовых конфигураций от 1 CPU, 1 Гб RAM, 40 Гб SSD-накопителя и от 219 руб/мес. до сервера с 8 CPU, 12 Гб RAM, 150 Гб NVMe-накопителя. Локация в РФ и Нидерландах.</li><li>VDS Форсаж: на AMD Epyc от 749 ₽/мес. Локации: РФ и Нидерланды.</li><li>CPU.Турбо: гибкая конфигурация на базе высокочастотных AMD Ryzen 9 от 624 ₽/мес. При покупке лицензии Битрикс дополнительная скидка 30% на 3 месяца аренды CPU.Турбо. Локация в РФ.</li><li>VDS Атлант: отказоустойчивый с автобэкапами от 1 619 ₽/мес. Локация: РФ.</li><li>VDS Storage: сервис как хранилище с гибкой конфигурацией от 704 ₽/мес. Локация: РФ</li></ul><p>Все тарифы доступны для тестирования по согласованию с отделом продаж. Для точного подбора конфигурации используйте гибкую настройку.</p><h2>2. UltraVDS: для малого бизнеса и стартапов</h2><p>Компания <a href="https://ultravds.com/">UltraVDS</a>, провайдер услуг виртуальных серверов (VPS/VDS), работает на рынке с 2014 года — предлагает решения для разных операционных потребностей. Сервисы UltraVDS можно использовать для развертывания торговых роботов, запуска чат-ботов, хостинга веб-сайтов, а также для создания FTP-хранилищ данных. Есть предложения для фрилансеров, цифровых агентств, корпоративных пользователей и стартапов, которым требуются функциональные инфраструктурные решения.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/edef3abb-6f77-4c69-be56-e22d90f379db.png" alt="" /></figure><h3>Технические особенности</h3><p>Серверы UltraVDS размещены в современном дата-центре, расположенном в Москве. Доступность сервиса (аптайм) составляет 99,98%, что обеспечивает высокую стабильность работы. Сетевая пропускная способность превышает 200 Мбит/с, при этом трафик предоставляется без ограничений.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-07-17/56ccb605-b64b-44f3-94b7-10e960541dda.png" alt="" /></figure><p>Система защиты от DDoS-атак способна обрабатывать трафик до 1,5 Тбит/с и поддерживает стабильность работы сервера даже при интенсивном внешнем воздействии. Лицензия на Windows Server входит в стоимость обслуживания в данном предложении. Это упрощает развертывание сервера: вам не нужно отдельно покупать и устанавливать лицензию. Плюс снижает общие операционные расходы для пользователей этой операционной системы.</p><h3>Тарифные планы</h3><p>Для новых пользователей UltraVDS предусмотрена возможность 3-дневного тестового периода, позволяющего оценить функциональность и производительность сервиса.</p><p>После тестового периода стоимость тарифов начинается от 119 рублей в месяц. На сайте доступен онлайн-калькулятор, позволяющий подобрать конфигурацию сервера и рассчитать итоговую стоимость.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-07-17/932d0cca-9f20-4723-8ae9-8d9c3218a08a.png" alt="" /></figure><p>Клиентам доступны различные варианты оплаты, включая ежемесячную систему без предоплаты. При авансовой оплате на период от 3 до 12 месяцев предоставляются скидки до 20%, размер которых зависит от выбранного срока. В случае досрочного прекращения использования сервиса, неиспользованный остаток средств возвращается на баланс пользователя.</p><h3>Поддержка и обслуживание</h3><p>Техническая поддержка UltraVDS работает круглосуточно, 7 дней в неделю. Среднее время ответа на запросы составляет до 15 минут. Связь со службой поддержки возможна по электронной почте и телефону, указанным на официальном сайте.</p><h2>3. RUVDS: 10 лет на рынке облачных решений</h2><p><a href="https://ruvds.com/ru-rub">RUVDS</a> — облачный провайдер, имеющий десятилетний опыт работы на рынке услуг виртуальных серверов (VPS/VDS). Является официальным партнером Huawei в России, работает по SLA. Компания предоставляет инфраструктурные решения, которые могут быть применены для широкого спектра задач, включая хостинг высоконагруженных интернет-магазинов, корпоративных порталов, игровых серверов, сложных backend-систем и чат-ботов.</p><p>Платформа RUVDS спроектирована для оптимизации процесса развертывания ресурсов. Одной из ее особенностей является маркетплейс, который позволяет быстро запускать серверы с предустановленным программным обеспечением. Это способствует ускорению старта проектов, снижая потребность в ручной настройке распространенных CMS, игровых серверов и сред разработки.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-07-17/aed25b96-b39b-4be9-b875-dc695645ef24.png" alt="" /></figure><h3>Тарифная политика и варианты оплаты</h3><p>RUVDS предлагает различные тарифные планы. Например, стоимость конфигурации Linux-сервера (1 CPU, 512 МБ RAM, 10 ГБ HDD, 1 IPv4) начинается от 139 ₽/месяц. Это может быть рассмотрено как экономичное решение для запуска небольших проектов и проведения тестирования.</p><p>Клиентам доступны разные опции оплаты:</p><ol><li>Ежемесячные платежи или предоплата на срок от 3 до 12 месяцев, при которой предоставляются скидки до 20%, зависящие от продолжительности периода.</li><li>Для проектов с динамической нагрузкой предусмотрена посекундная тарификация, оплата по которой взимается только за фактически использованные ресурсы. Неиспользованный остаток средств в рамках этой модели возвращается на баланс пользователя</li></ol><p>Дополнительно, до конца 2025 года панель управления ISP Manager для сервера и сайта предоставляется без дополнительной платы при создании любого VPS.</p><h3>Глобальная инфраструктура и стабильность</h3><p>Инфраструктура включает 17 дата-центров уровня Tier III, расположенных по всему миру. Это один из самых больших показателей по количеству геолокаций среди российских провайдеров. Для работы используются корпоративное оборудование и накопители (HDD, SSD, NVMe), чтобы обеспечить стабильную работу и производительность размещенных проектов.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/3f3c970e-820f-4f0e-9b53-f227950e298b.png" alt="" /></figure><h3>Поддержка клиентов и доступные ресурсы</h3><p>Техническая поддержка RUVDS доступна круглосуточно, 7 дней в неделю. Среднее время ответа на запросы через тикет-систему или онлайн-чат составляет 15 минут. Клиентам предоставляются полные административные права и консультации по вопросам запуска и настройки серверов. Для самостоятельного изучения доступна база знаний, включающая инструкции и руководства.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-07-17/c086a963-2d51-4ada-86c8-0c1704cf8230.png" alt="" /></figure><h3>Безопасность и масштабирования</h3><p>В контексте безопасности данных, RUVDS предлагает несколько решений:</p><p>- Встроенная защита от DDoS-атак, способствующая поддержанию бесперебойной работы серверов при внешнем воздействии.</p><p>- Стандартный IPv4-адрес включен в стоимость каждой виртуальной машины, с опцией аренды дополнительных IP-адресов.</p><p>- API, соответствующий OpenAPI 3.0.0, предоставляет возможности для интеграции и автоматического масштабирования серверных ресурсов в зависимости от нагрузки.</p><p>- Компания официально подтверждает соответствие требованиям ФСТЭК и ФЗ-152 по защите персональных данных, что обеспечивает соблюдение соответствующих законодательных норм.</p><h2>4. McHost: решения для бизнеса разного масштаба</h2><p><a href="https://mchost.ru/"> McHost</a> предоставляет комплексные хостинговые решения, включая виртуальный хостинг и VPS/VDS с NVMe-накопителями. Сервис поддерживает популярные CMS (WordPress, Joomla, 1С-Битрикс) с оптимизированными настройками и автоматической установкой через панель управления.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/2ccc459a-8df5-41b6-bbf9-b751bed2e757.png" alt="" /></figure><p>McHost ориентирован на широкий круг клиентов:</p><ul><li>владельцы сайтов-визиток, блогов и лендингов — благодаря низким тарифам и полному набору опций;</li><li>интернет-магазины с небольшой нагрузкой — тарифы с SSD-накопителями и автоматическим резервным копированием обеспечивают стабильную работу;</li><li>разработчики, которым нужны<br />VPS/VDS с root-доступом — работают серверы на KVM-виртуализации с ОС Linux и Windows;</li><li>госучреждения и компании,<br />работающие с персональными данными — соответствие 152-ФЗ и размещение в дата-центрах Tier III в Москве.</li></ul><h3>Особенности сервиса</h3><p>McHost поддерживает стабильную работу с аптаймом 99.9% за счет размещения оборудования в дата-центрах уровня Tier III — в Москве и Нидерландах.</p><p>Сервис предоставляет защиту от DDoS-атак, автоматическое резервное копирование раз в два дня с хранением данных в течение 30 дней для виртуального хостинга и 14 дней для VPS, а также поддержку российских криптографических стандартов. Клиентам доступны различные варианты размещения: от виртуального хостинга с SSD (от 157.5 ₽/мес) до выделенных серверов с NVMe-накопителями.</p><h3>Технические параметры и условия</h3><p>Инфраструктура McHost базируется на серверах Dell с NVMe-накопителями и процессорами Intel Xeon (частота ядер от 2.35 ГГц). Для виртуального хостинга используется CloudLinux с технологией CageFS, обеспечивающей изоляцию аккаунтов. Поддержка российских ОС («Альт») подтверждена для VPS-тарифов.</p><p>В техподдержку можно обратиться по телефону, через тикет или в Telegram-боте. Время ответа — до 10 минут.</p><p>Текущие тарифы:</p><ul><li>Виртуальный хостинг: от 157 ₽/мес<br />(3 ГБ SSD, 1 сайт).</li><li>VPS: от 396 ₽/мес (15 ГБ SSD, 1<br />ядро CPU).</li><li>Выделенные серверы: от 3 000 ₽/мес<br />(32 ГБ RAM, 2×1 ТБ HDD).</li></ul><h2>5. UFO Hosting: VPS/VDS и выделенные серверы с портом до 10 Гбит/с и безлимитным трафиком</h2><p><a href="https://ufo.hosting/">UFO Hosting </a>предлагает VPS/VDS и выделенные серверы на партнёрской инфраструктуре IXcellerate (Tier III). В портфолио — недорогие виртуальные машины и серверы с портом 10 Gbps для проектов, которым нужна стабильность без завышенных цен.</p><p>Сервис подходит для пользователей разных масштабов: от фрилансеров и веб‑студий до средних и крупных компаний. Для DevOps‑специалистов доступны API и инструменты автоматизации.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-19/3cfc6e79-bab0-48ab-862b-f523c0ad24e8.png" alt="" /></figure><h3>Основные сценарии использования</h3><ul><li>корпоративные сайты, CRM‑системы и веб‑приложения;</li><li>аналитические сервисы и SaaS‑продукты;</li><li>инфраструктура для разработки и тестирования;</li><li>задачи фрилансеров, агентств и digital‑команд.</li></ul><h3>Формат работы, особенности и интеграции</h3><p>Серверы установлены в российском дата‑центре Tier III (IXcellerate), что означает резервирование по питанию и каналам связи. Заявленный аптайм — 99,98 %. Поддержка работает круглосуточно в тикетах, чате и по телефону; среднее время ответа 5–10 минут.</p><p>Сервис UFO Hosting делает акцент на безопасности и гибкости. Есть сеть с защитой от DDoS, возможность горячего расширения ресурсов, автоматическое развёртывание из шаблонов и API для интеграции. Поддерживаются популярные фреймворки и CMS, есть интеграции с GitLab, Telegram и DockerHub. Бэкапы, снапшоты и резервирование входят в стандартный набор, так что восстанавливать тестовую среду не придётся вручную.</p><p>В панели управления можно автоматически установить популярные CMS, панели управления, хранилища и DevOps‑инструменты. Это экономит время на настройку и подходит тем, кто не хочет поднимать всё с нуля.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-08-06/e4433ae3-898b-4c14-90c1-2a4bbb8b13a1.png" alt="" /></figure><h3>Условия использования и тарифы</h3><p>Базовые конфигурации начинаются от 577 руб./месяц. Заявленная скорость порта — до 10 Gbps, что подходит для проектов, где много трафика.</p><p>Есть возможность бесплатно попробовать сервис присутствует, но предоставляется по запросу в поддержку, а при оплате на срок от трёх месяцев действуют скидки, а также регулярно проводятся акции: это поможет оптимизировать бюджет.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-08-06/1e2e0191-1194-4a60-a612-fcac5d8cf76d.png" alt="" /></figure><p>В целом, UFO Hosting выглядит как практичное решение для тех, кому нужны производительные VPS/VDS и выделенные серверы в России. При выборе стоит оценить, насколько конфигурации подходят под конкретные нагрузки и есть ли необходимость в интеграциях из коробки.</p><h2>6. Timeweb: хостинг для веб-проектов</h2><p><a href="https://timeweb.com/">Timeweb </a>предоставляет услуги хостинга для различных типов веб-проектов. Сервис поддерживает популярные CMS, включая WordPress, 1C-Битрикс и Joomla, что делает его подходящим как для личных блогов, так и для корпоративных сайтов.</p><p>Платформа использует собственную панель управления с инструментами для работы с сайтами, базами данных и резервными копиями. Ежедневное автоматическое резервное копирование с хранением данных до 30 дней включено во все тарифные планы. Базовая защита от DDoS-атак доступна для всех клиентов без дополнительной платы.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/b443bfef-bccb-4672-bd55-cb67a1146bc3.png" alt="" /></figure><p>Инфраструктура Timeweb размещена в дата-центрах уровня Tier III в России (Санкт-Петербург) и Казахстане (Алматы). Гарантированный показатель uptime составляет 99.98%. Поддерживаются современные технологии: PHP версий от 5.3 до 8.4, MySQL от 5.6 до 8.0, а также Perl, Python, SSH, FTP и Cron.</p><p>Тарифные планы:</p><ul><li>Year+: от 164 ₽/мес (2 сайта, 15<br />ГБ NVMe, 2 БД);</li><li>Optimo+: от 248 ₽/мес (15 сайтов,<br />40 ГБ NVMe, безлимитные БД);</li><li>Century+: от 347 ₽/мес (35 сайтов,<br />50 ГБ NVMe, безлимитные БД);</li><li>Millennium+: от 482 ₽/мес (60<br />сайтов, 60 ГБ NVMe, безлимитные БД).</li></ul><p>Все тарифы включают бесплатный SSL-сертификат, 10 ГБ почтовой квоты с неограниченным количеством ящиков и DNS-хостинг. При оплате годового тарифа предоставляется домен в зонах .RU/.РФ в подарок.</p><p>Техническая поддержка доступна круглосуточно через онлайн-чат, тикет-систему и по телефону. Среднее время ответа не превышает 15 минут. Новые клиенты могут протестировать сервис бесплатно в течение пробного периода.</p><h2>7. Reg.ru: комплексные решения для сайтов и доменов</h2><p><a href="https://www.reg.ru/">Reg.ru </a>сочетает услуги хостинга и регистрации доменов, что упрощает управление веб-проектами. Компания работает с 2005 года, имеет статус аккредитованного регистратора доменных имён в зонах .RU и .РФ.</p><h3>Функциональные возможности</h3><p>Платформа предоставляет доступ к трём панелям управления: ISPmanager, cPanel и Plesk. Это позволяет выбрать наиболее удобный интерфейс для работы с сайтами. Все тарифы включают бесплатный SSL-сертификат от Let’s Encrypt, который автоматически устанавливается при создании сайта.</p><p>Начинающим пользователям доступен конструктор сайтов с готовыми шаблонами. Поддерживаются популярные CMS, включая WordPress, Joomla и 1С-Битрикс. Ежедневное резервное копирование данных с хранением копий в течение 30 дней входит в стандартный набор услуг.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/c1ac0c6a-51ae-4ae5-8875-f18a01ffdc2c.png" alt="" /></figure><h3>Техническая инфраструктура</h3><p>Серверы размещены в дата-центрах уровня Tier III в Москве. Средний показатель uptime составляет 99.9%, что подтверждается ежемесячной статистикой. Подключение к сети осуществляется по выделенным каналам со скоростью до 1 Гбит/с на выделенных серверах.</p><h3>Поддержка и тарифы</h3><p>Техническая поддержка доступна 24/7 через онлайн-чат и тикет-систему. Среднее время ответа составляет 15-20 минут. Для срочных вопросов можно обратиться по телефону.</p><p>Тарифы — от 151 ₽/мес (7 ГБ SSD, 15 сайтов). При регистрации домена в зонах .RU или .РФ предоставляется скидка на другие доменные имена.</p><h2>8. Спринтхост: хостинг с персональным подходом</h2><p><a href="https://sprinthost.ru/">Sprinthost</a> предлагает услуги хостинга с акцентом на индивидуальную поддержку клиентов. Сервис работает с 2011 года и специализируется на VPS-решениях для различных веб-проектов.</p><h2>Особенности сервиса</h2><p>Компания предоставляет персонального менеджера для каждого клиента, который помогает с настройкой сервера и решением технических вопросов. А если вы остались недовольны услугами, то в течение 30 дней сервис вернёт деньги. Sprinthost проводит бесплатные обучающие вебинары по DevOps и администрированию серверов.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/7acc90d0-655a-4cda-906f-a7e5ad4f9a8e.png" alt="" /></figure><h3>Технические характеристики и тарифы</h3><p>Инфраструктура размещена в дата-центрах Москвы и Санкт-Петербурга с аптаймом 99.9%. Поддерживаются современные технологии разработки, включая Ruby on Rails, Node.js, Python и Docker. Все серверы используют SSD-накопители с гарантированной скоростью чтения/записи.</p><p>Тарифные планы:</p><ul><li>Start: 290 ₽/мес (1 ядро, 1 ГБ<br />RAM, 15 ГБ SSD);</li><li>Turbo: 1 900 ₽/мес (4 ядра, 8 ГБ<br />RAM, 100 ГБ NVMe).</li></ul><h3>Поддержка</h3><p>Техническая помощь доступна 24/7 через тикет-систему и онлайн-чат. Среднее время ответа составляет 10-15 минут. Для корпоративных клиентов предусмотрена приоритетная поддержка по телефону.</p><h2>Как выбрать хостинг в 2025 году</h2><p>Выбор хостинга зависит от типа проекта и его требований. Для небольших сайтов и блогов подойдет виртуальный хостинг с поддержкой популярных CMS — важно проверить наличие автоматических бэкапов и базовой защиты от DDoS. Если проект связан с обработкой персональных данных, убедитесь, что провайдер соответствует 152-ФЗ и использует сертифицированное оборудование.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/3a0b1d01-c4e0-424d-86b2-8988d43bcdb1.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/b3c26558-3a50-4eb3-a9f3-89c899fd9e59.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/3408c453-b5db-44ce-b6ab-f1b3bcb5abd1.png" alt="" /></figure><p>Для высоконагруженных сервисов и интернет-магазинов лучше рассматривать VPS или выделенные серверы. Обратите внимание на тип накопителей (SSD/NVMe), возможность масштабирования ресурсов и аптайм дата-центров (рекомендуется от 99.9%).</p><p>Перед покупкой протестируйте сервис — большинство провайдеров предлагают пробный период. Проверьте скорость работы панели управления и отзывчивость поддержки. Не забывайте о резервном копировании: даже если хостинг предоставляет эту услугу, дублируйте критически важные данные самостоятельно.</p><p>Главное правило — выбирайте решение, которое покрывает текущие потребности проекта. Важно, чтобы конфигурацию можно было оперативно менять по мере роста запросов и масштабирования бизнеса. Технологии меняются быстро, и гибкость конфигурации часто важнее сиюминутной экономии.</p><h2>FAQ</h2><h3>Что такое виртуальный хостинг и когда его выбирать?</h3><p>Виртуальный хостинг — это экономичное решение, где один физический сервер делит ресурсы между множеством сайтов. Подходит для небольших проектов с низкой нагрузкой: личных блогов, лендингов или стартовых страниц.</p><p>Преимущества: низкая стоимость, простота управления через панели, автоматические обновления и базовая защита. Минусы: ограниченные ресурсы; производительность зависит от соседних сайтов; минимальный контроль над настройками.</p><h3>Что такое VPS/VDS и для каких проектов он подходит?</h3><p>VPS (Virtual Private Server) или VDS — это виртуальный сервер с выделенными ресурсами (процессор, память, диск), предоставляющий доступ для полной настройки. Идеален для проектов среднего масштаба: интернет-магазинов, API, SaaS, чат-ботов, корпоративных порталов или приложений с умеренным трафиком.</p><p>Преимущества: гибкость конфигураций, выбор ОС, изоляция ресурсов. Минусы: требует базовых навыков администрирования, стоимость выше, чем у виртуального хостинга.</p><h3>Что такое выделенный сервер и когда его использовать?</h3><p>Выделенный сервер — это физический сервер, полностью зарезервированный под ваш проект. Подходит для высоконагруженных систем: крупных интернет-магазинов, игровых платформ, корпоративных ERP или аналитических сервисов с большим трафиком.</p><p>Преимущества: максимальная производительность, полный контроль, высокая отказоустойчивость. Минусы: высокая цена, сложность настройки и обслуживания.</p><h3>В чём основные различия между виртуальным хостингом, VPS и выделенным сервером?</h3><p>Виртуальный хостинг — самый дешёвый и простой, но ресурсы делятся между пользователями, что ограничивает производительность (до 1000–2000 посетителей в сутки).</p><p>VPS обеспечивает выделенные ресурсы и гибкость, справляясь с нагрузкой до 5000–10 000 пользователей в сутки.</p><p>Выделенный сервер — максимум мощности для пиков свыше 10 000 пользователей, но требует значительных затрат и технических знаний.</p><p>Выбор зависит от масштаба: виртуальный для старта, VPS для роста, выделенный для enterprise.</p><h3>Нужны ли навыки администрирования для хостинга?</h3><p>Для виртуального хостинга навыки не нужны — управление идёт через интуитивные панели, а провайдеры обеспечивают обновления и базовую поддержку. Для VPS желательны базовые знания (настройка ОС, установка ПО), хотя многие провайдеры предлагают помощь. Для выделенного сервера навыки администрирования необходимы, так как вы полностью отвечаете за сервер, хотя провайдеры могут предлагать платное администрирование.</p>]]></content:encoded>
    </item>
    <item>
      <title>10 библиотек Python, которые меняют карьеру</title>
      <link>https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru</link>
      <comments>https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru</guid>
      <description><![CDATA[<p>10 библиотек Python, которые помогут прокачаться в аналитике, ML и разработке. Как они работают и почему меняют карьеру.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru">10 библиотек Python, которые меняют карьеру</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Jupyter Notebook]]></category>
      <category><![CDATA[Визуализация]]></category>
      <category><![CDATA[Образование]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Анализ данных]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 17 Jul 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>У Python тысячи библиотек, но лишь немногие действительно меняют карьеру. Они помогают не просто решать задачи, а ускорять проекты, прокачивать навыки и выходить на следующий уровень в аналитике, машинном обучении и разработке. В этом материале мы собрали 10 библиотек, которые помогут зарабатывать на Python и развивать навыки.</p><h2>1. Pandas</h2><p>Pandas — библиотека для работы с данными в Python, позволяющая легко загружать, анализировать, очищать и преобразовывать числовую информацию в удобной табличной форме. По сути, это Excel, который смог, и позволяет делать всё автоматизировано и на порядки быстрее.</p><p>Библиотека строится вокруг двух ключевых структур: <b>Series</b> (одномерный массив с индексами); <b>DataFrame </b>(таблица с индексами и колонками).</p><h3>Какие задачи решает библиотека</h3><p>Pandas полезна для следующих задач:</p><ul><li>Сам анализ данных: можно быстро фильтровать, группировать, агрегировать и строить сводные таблицы.</li><li>Очистка данных: удаляем пустые строки, заменяем значения, приводим типы.</li><li>Загрузка данных из CSV, Excel, SQL.</li><li>Визуальная разведка данных (EDA) перед построением моделей.</li><li>Подготовка данных для ML и отчётов.</li><li>Автоматизация отчётов и ETL-пайплайнов.</li></ul><p>Благодаря Pandas аналитик превращается в инженера данных, а ML-специалист может сосредоточиться на моделях, а не на ручной подготовке датасетов.</p><h3>Как пользоваться</h3><p>Ниже разберём простейший кейс: нужно загрузить данные о зарплатах разработчиков из CSV, посчитать среднюю зарплату по языкам программирования и отобрать топ-5.</p><h3>Почему это меняет карьеру</h3><p>Работа с Pandas становится границей между знанием Python и умением решать задачи бизнеса. Для <b>джуна </b>это шанс сразу показать практическую пользу: выгрузки, отчёты и базовый анализ можно делать в десятки раз быстрее и аккуратнее, чем вручную в эксельке.</p><p>Для <b>аналитика</b> Pandas превращается в главный рабочий инструмент, позволяя не просто проверять гипотезы и делать сводные таблицы, а строить полноценные отчётные пайплайны, автоматизировать рутинные выгрузки и концентрироваться на сути данных, а не на правках ручками.</p><p>Для <b>ML-инженера</b> владеть Pandas — значит уметь готовить датасеты качественно; быстро очищать и приводить данные к нужному виду, что напрямую влияет на результат моделей. Без этого работа над проектами машинного обучения часто превращается в бесконечную возню с данными.</p><p>Наконец, даже для <b>разработчиков</b> Pandas может стать неожиданным бустом в карьере. Например, когда нужно автоматизировать отчёты для бизнеса или быстро анализировать логи и данные из БД без поднятия дашбордов — Pandas даёт гибкость и скорость, которые редко даёт что-то ещё в экосистеме Python.</p><h2>2. Django</h2><p>Django — фреймворк для веб-разработки на Python, который позволяет быстро создавать надежные и масштабируемые веб-приложения. Он следует принципам DRY (Don’t Repeat Yourself — не повторяй себя), предоставляя разработчику ORM, роутинг, систему авторизации, админку, работу с формами, шаблонами и инструментами безопасности из коробки.</p><p>Django подходит как стартапам, которым нужно быстро выйти на рынок, так и крупным проектам с миллионами пользователей. Это не просто библиотека, а полноценный каркас для построения и сопровождения веб-сервисов.</p><h3>Какие задачи решает библиотека</h3><p>Каркас, действительно, каркасный. Задачи следующие:</p><ul><li>Создание веб-приложений и API любой сложности.</li><li>Быстрая разработка MVP, прототипов и коммерческих проектов.</li><li>Упрощение работы с базами данных через ORM, без написания сырого SQL.</li><li>Построение административных панелей для управления данными без ручной разработки.</li><li>Гибкая маршрутизация и работа с формами, валидацией и шаблонами.</li><li>Реализация аутентификации, авторизации и защиты приложений.</li></ul><p>Django позволяет сосредоточиться на бизнес-логике и продукте, не тратить недели на настройку инфраструктуры.</p><h3>Как пользоваться</h3><p>Устанавливаем:</p><p>Создаем проект и приложение:</p><p>Пример модели:</p><p>Миграция базы данных:</p><p>Создание админки:</p><p>После этого можно запустить сервер:</p><p>И перейти по адресу http://127.0.0.1:8000/admin для управления записями через готовую админ-панель.</p><h2>3. PyTorch</h2><p>PyTorch — мощная библиотека Python. Она позволяет строить и обучать нейронные сети, проводить вычисления с автоматическим дифференцированием и работать с GPU для ускорения самих вычислений.</p><p>Главное отличие PyTorch от других ML-фреймворков — динамическая вычислительная графика (define-by-run): модель строится и изменяется во время выполнения кода, что даёт гибкость при создании и отладке сложных моделей.</p><p>Сегодня PyTorch используется в продакшен системах, научных исследованиях, компьютерном зрении, NLP и генеративных моделях, занимая ведущее место в индустрии.</p><h3>Какие задачи решает библиотека</h3><p>В функционал PyTorch входят:</p><ul><li>Построение нейронных сетей любой сложности (CNN, RNN, трансформеры);</li><li>Обучение и тестирование моделей на CPU и GPU;</li><li>Реализация кастомных слоёв и loss-функций;</li><li>Разработка и деплой ML/AI моделей в продакшен;</li><li>Быстрая итерация гипотез с удобной отладкой.</li></ul><p>С PyTorch можно начать с простых нейронных сетей, а затем перейти к реализации современных архитектур.</p><h3>Как пользоваться</h3><p>Установим PyTorch (на CPU, для GPU потребуется версия с CUDA):</p><p>Рассмотрим кейс обучения простой нейронной сети для классификации рукописных цифр MNIST.</p><p>После обучения можно использовать torch.save() для сохранения модели и torch.load() для загрузки в продакшн.</p><h3>Почему это меняет карьеру</h3><p>PyTorch — билет в мир современной разработки AI и машинного обучения. Владение инструментом даёт <b>разработчику</b> возможность уверенно войти в области, которые продолжают оставаться топовыми на рынке: искусственный интеллект, компьютерное зрение, NLP, генерация изображений и видео и т.д.</p><p>Для <b>начинающего ML/AI-специалиста </b>PyTorch помогает лучше понять, как устроены нейронные сети, и под капотом увидеть, как происходят вычисления. Это ускоряет рост навыков и делает разработчика востребованным в исследованиях и R&amp;D-проектах.</p><p>Для <b>дата-сайентистов</b> PyTorch позволяет превратить исследовательские ноутбуки в готовые к деплою модели, благодаря PyTorch Lightning, TorchScript и ONNX.</p><p>Для<b> разработчиков, которые хотят выйти на рынок AI</b>, PyTorch — это мастхев: проекты в стартапах и крупных компаниях всё чаще строятся вокруг него. Умение писать кастомные loss-функции, проектировать сложные пайплайны обучения, настраивать обучение на кластерах и GPU — компетенции, которые существенно бустят зарплату.</p><p>PyTorch в целом помогает расширять портфолио: с ним можно создавать генеративные модели, строить LLM, участвовать в соревнованиях и работать с самыми современными подходами в машинном обучении.</p><h2>4. Polars</h2><p>Polars — современная библиотека для обработки данных в Python, созданная как альтернатива Pandas. Она использует колоночную архитектуру и многопоточность, что позволяет работать с большими объёмами данных значительно быстрее и с меньшим потреблением памяти.</p><p>Polars вдохновлена Pandas, но её API оптимизировано для производительности и удобства, а также даёт разработчику возможность писать цепочки ленивых вычислений, которые оптимизируются перед выполнением. Это делает её отличным инструментом для аналитиков, дата-инженеров и дата-сайентистов, которым нужно обрабатывать данные быстро.</p><h3>Какие задачи решает библиотека</h3><p>Polars явно есть, чем гордиться:</p><ul><li>Загрузка, очистка и преобразование больших датасетов;</li><li>Анализ данных с использованием цепочек преобразований;</li><li>Быстрая агрегация и группировка данных;</li><li>Ленивые вычисления: построение пайплайнов преобразования данных, которые выполняются только при вызове collect().</li><li>Обработка данных, которые не помещаются в память, за счёт эффективности и колоночной архитектуры.</li></ul><p>Если Pandas начинает притормаживаться на данных в несколько гигабайт, Polars обычно продолжает работать быстро, позволяя без боли обрабатывать большие CSV.</p><h3>Как пользоваться</h3><p>Установка:</p><p>Давайте загрузим данные и проведем базовые трансформации:</p><p>А вот и пример ленивых вычислений:</p><p>В чем особенность:</p><ul><li>pl.read_csv загружает данные сразу.</li><li>pl.scan_csv создаёт план вычислений для последующей оптимизации.</li><li>Используются выражения (pl.col, .with_columns, .agg), которые композируются без создания промежуточных копий, это ускоряет процесс.</li></ul><h3>Почему это меняет карьеру</h3><p>Polars меняет карьеру, потому что даёт преимущество в скорости и эффективности при работе с данными. Там, где Pandas уже не справляется, полярный медведь приходит на помощь.</p><p>Для <b>дата-инженеров</b> Polars полезен при построении ETL и пайплайнов обработки данных, где важна скорость и предсказуемое потребление ресурсов. Его можно использовать в продакшен-скриптах, для подготовки данных к ML и для автоматизации отчётности.</p><p>Для <b>дата-сайентистов </b>Polars даёт возможность анализировать больше данных за меньшее время, быстро итерировать гипотезы и ускорять исследования. Его API достаточно близок к Pandas, поэтому переход не требует месяцев переучивания.</p><p>Освоение Polars показывает работодателям, что ты не просто знаешь стандартные инструменты, но умеешь выбирать оптимальные решения для реальных задач, повышая эффективность работы команды. В эпоху роста данных это критично для любого Python-разработчика, работающего с аналитикой и машинным обучением.</p><h2>5. FastAPI</h2><p>FastAPI — современный фреймворк для создания API на Python, заточенный под скорость, асинхронность и валидацию данных из коробки. Он построен на Starlette и Pydantic, автоматически создаёт OpenAPI-документацию, поддерживает асинхронное программирование и позволяет писать производительные REST и WebSocket API с минимальным количеством кода.</p><p>Вместо долгой настройки, как у Flask или Django, в FastAPI многое готово изначально: удобная работа с запросами и ответами, декларативная валидация, документация Swagger, асинхронность и высокая производительность без лишних усилий.</p><h3>Какие задачи решает</h3><p>Задач, действительно, много:</p><ul><li>Быстрая разработка REST API для мобильных и веб-приложений;</li><li>Создание бэкенда для ML/DS моделей (деплой моделей в виде API);</li><li>Построение микросервисов с хорошей производительностью;</li><li>Реализация websocket-серверов и асинхронных API;</li><li>Подготовка внутренних инструментов или бэкендов для MVP.</li></ul><p>FastAPI помогает быстро запускать API и уверенно масштабировать его в полевых условиях. Это один из немногих фреймворков Python, который по скорости работы сопоставим с Node.js и Go.</p><h3>Как пользоваться</h3><p>Во-первых, нужно установить FastAPI и Uvicorn (используем ASGI-сервер для запуска):</p><p>Простейший API-пример с эндпоинтом GET /:</p><p>Запускаем сам сервер:</p><p>После запуска API будет доступен по адресу http://127.0.0.1:8000/. Автоматически доступна интерактивная документация Swagger по адресу http://127.0.0.1:8000/docs.</p><p>FastAPI поддерживает валидацию параметров запроса, тел запросов и путей прямо через типы Python. Например, простой эндпоинт с параметром:</p><p>При вызове http://127.0.0.1:8000/items/10?q=test FastAPI автоматически проверит, что item_id — это число, и распарсит q как строку.</p><h3>Почему это меняет карьеру</h3><p>FastAPI — билет в мир бэкенда, где скорость и чистота кода имеют довольно высокое значение. Для <b>Python-разработчика </b>это возможность быстро освоить создание API и микросервисов, не увязнув в громоздкой настройке, как в Django, и при этом получить систему, готовую к продакшену.</p><p>Для <b>ML-специалиста</b> FastAPI становится инструментом для деплоя моделей: можно обернуть пайплайн предсказаний в API, подключить авторизацию или логирование и получить работающий сервис за считанные дни.</p><p>Вообще умение быстро поднимать и поддерживать API — навык, который ценят в бигтехе и стартапах. На разработчиков, которые владеют FastAPI, часто равняются: они умеют превращать идеи бизнеса в работающие сервисы за минимальное время.</p><h2>6. Typer</h2><p>Typer — современная библиотека для создания CLI-приложений на Python с минимальным количеством кода и автоматической генерацией документации. Автор библиотеки — Себастьян Рамирес, создатель FastAPI.</p><p>Главная особенность Typer — использование type hints для автоматического парсинга аргументов командной строки. Вы получаете удобную и читаемую CLI с поддержкой автодополнения и цветного вывода за считанные минуты.</p><h3>Какие задачи решает библиотека</h3><p>Список задач такой:</p><ul><li>Создание CLI-утилит любого уровня сложности.</li><li>Быстрое прототипирование и упаковка Python-скриптов в удобные инструменты для продакшена.</li><li>Генерация подробной справки (--help) и автодополнения команд.</li><li>Облегченная поддержка и масштабирование CLI за счёт структуры и читаемого кода.</li><li>Организация CLI с подкомандами, вложенными аргументами и обработкой ошибок.</li></ul><p>Typer использует аннотацию типов и минимум шаблонного кода.</p><h3>Как пользоваться</h3><p>Установка:</p><p>Пример минимальной CLI:</p><p>Теперь можно запустить из консоли:</p><p>Результат будет такой: Привет, Алиса! Тебе 25 лет.</p><h3>Почему это меняет карьеру</h3><p>Typer меняет карьеру тем, что открывает путь к созданию удобных CLI-инструментов, которые автоматизируют рутину и повышают продуктивность.</p><p>С Typer можно быстро превращать свои Python-скрипты в надежные утилиты, которыми удобно пользоваться и другим разработчикам, и сотрудникам из других отделов. CLI-приложения часто становятся клеем инфраструктуры: они позволяют автоматизировать деплой, миграции БД, сбор данных, интеграцию с внешними API и локальную разработку.</p><p>Если вы <b>Data Scientist или ML-инженер</b>, Typer позволяет оборачивать пайплайны в CLI, которые легко запускать из Jenkins, Airflow или вручную. Если вы <b>DevOps или Backend-инженер</b>, можете создавать CLI для работы с инфраструктурой и сервисами без сложных зависимостей.</p><p>Кроме того, работа с Typer улучшает навык структурирования кода, понимание CLI, использования type hints и разработки инструментов, которые делают работу проще для других. А это, очевидно, ценится в любой команде и повышает востребованность специалиста.</p><h2>7. Rich</h2><p>Rich — библиотека Python для красивого форматирования и интерактивного отображения информации в терминале. С её помощью можно выводить цветные таблицы, маркдаун, прогресс-бары, подсвеченный синтаксис кода, деревья каталогов и логирование в понятной и привлекательной форме.</p><p>Rich создана для того, чтобы «оживить» консоль Python, сделать логи удобными для восприятия, а CLI-инструменты — профессионально выглядящими без лишних усилий. Это библиотека, которая улучшает и UX, и DX.</p><h3>Какие задачи решает</h3><p>Про красоту не забываем! Задачи следующие:</p><ul><li>Цветное и структурированное логирование, понятное при чтении логов в реальном времени.</li><li>Отображение прогресс-баров для долгих операций.</li><li>Вывод таблиц, деревьев каталогов, JSON прямо в терминале.</li><li>Подсветка синтаксиса кода для CLI-инструментов.</li><li>Создание CLI-интерфейсов, которые выглядят профессионально и современно.</li><li>Улучшение читаемости при отладке скриптов.</li></ul><p>С помощью Rich можно быстро сделать понятными даже сложные данные при отладке или демонстрации.</p><h3>Как пользоваться</h3><p>Установка Rich:</p><p>Для примера выведем таблицу с подсветкой в консоли:</p><p>В результате в терминале получится цветная таблица, которая выглядит понятно и презентабельно.</p><h3>Почему это меняет карьеру</h3><p>Rich — это библиотека, которая помогает быстро повысить качество любого CLI-инструмента или дев-опыт в команде. <b>Разработчик</b>, который использует Rich, делает свои инструменты удобными не только для себя, но и для коллег: логирование становится понятным, а отладка скриптов — наглядной.</p><p>Во многих стартапах и продвинутых командах важна скорость обратной связи при тестировании пайплайнов и автоматизаций, и Rich помогает выводить ключевую информацию максимально читаемо.</p><p>Кроме того, Rich позволяет быстро создавать CLI-интерфейсы, которые выглядят как продакшен-продукты, даже если это внутренние инструменты. Руководство будет радоваться и думать о вас как о крутом разрабе.</p><p>Для <b>дата-инженеров и разработчиков DevOps</b> Rich полезна при создании админ-утилит и при мониторинге пайплайнов, для <b>Python-разработчиков</b> — при создании библиотек и фреймворков с CLI.</p><h2>8. LangChain</h2><p>LangChain — фреймворк для создания приложений на базе LLM, например, GPT, Claude, Mistral, Gemini. Он позволяет строить цепочки обработки запросов, интегрировать LLM с данными и инструментами, добавлять память и управление состояниями, а также связывать работу модели с внешними API и базами знаний.</p><p>LangChain предоставляет удобный слой абстракции над вызовами LLM и ускоряет разработку чат-ботов, RAG-приложений, агентов с инструментами, систем анализа документов и других AI-сервисов.</p><h3>Какие задачи решает</h3><p>Список внушительный:</p><ul><li>Интеграция LLM в Python-приложения без необходимости писать тот самый клеевой код вручную.</li><li>Построение цепочек с последовательной обработкой сообщений, включая преобразования и вызовы внешних функций.</li><li>Добавление памяти в чат-боты для сохранения истории общения и контекста.</li><li>Использование агентов для динамического вызова инструментов (веб-поиск, базы данных, API).</li><li>Создание RAG-систем с интеграцией LLM и векторных БД.</li><li>Быстрая сборка прототипов LLM-приложений, которые можно развернуть в продакшен.</li></ul><h3>Как пользоваться</h3><p>Установка:</p><p>Создадим простую цепочку с чатом GPT:</p><p>Благодаря единым абстракциям, можно гибко комбинировать цепочки, память и вызов внешних инструментов, не усложняя код.</p><h3>Почему это меняет карьеру</h3><p>LangChain меняет карьеру, потому что открывает новый пласт Python-разработки в AI и LLM-инженерии, быстро превращая пользователя GPT в создателя полноценных AI-приложений. Вместо того чтобы писать хаотичный клеевой код, вы начинаете системно проектировать цепочки запросов, учитесь строить продуманные промпты и объединять их с инструментами, памятью и внешними API.</p><p>Работа с LangChain погружает в практическую LLM-инженерию: вы начинаете создавать RAG-приложения, которые умеют искать и анализировать данные перед генерацией ответа и строить агентов. Это востребовано в продуктах, где нужно подключать ИИ к базам знаний, автоматизировать задачи и разрабатывать интерактивные системы, которые реально используют модели в продакшене.</p><p>LangChain позволяет быстро собирать и запускать MVP AI-продуктов, что дает конкурентное преимущество при создании стартапов или внутренних сервисов. А ещё учит мыслить структурами и проектировать масштабируемую архитектуру LLM-приложений и видеть, как генеративный ИИ можно превратить в рабочий инструмент.</p><h2>9. SQLAlchemy</h2><p>SQLAlchemy — это мощная ORM и toolkit для работы с базами данных в Python, позволяющая писать SQL-запросы декларативно, создавать модели таблиц и управлять транзакциями в Python-коде без ручного написания SQL.</p><p>Библиотека даёт разработчику два уровня контроля:</p><ul><li>Core: низкоуровневая работа с SQL выражениями и соединениями;</li><li>ORM: высокоуровневая декларативная работа с моделями, классами и связями между таблицами.</li></ul><p>SQLAlchemy поддерживает PostgreSQL, MySQL, SQLite, Oracle и другие СУБД, давая единую абстракцию, без привязки к конкретному движку.</p><h3>Какие задачи решает</h3><p>Пул задач следующий:</p><ul><li>Описание таблиц в виде Python-классов и управление ими через сессии;</li><li>Создание, чтение, обновление и удаление данных;</li><li>Миграция SQL на декларативный стиль без потери гибкости;</li><li>Полный контроль над транзакциями и выполнением запросов;</li><li>Работа с асинхронными приложениями при создании FastAPI/Django-приложений;</li><li>Экранирование параметров, которое снижает вероятность SQL-инъекций и ошибок.</li></ul><h3>Как пользоваться</h3><p>Создадим минимальный пример для SQLite с таблицей пользователей:</p><p>Этот код создаёт базу example.db, таблицу users, добавляет туда одного пользователя и выводит всех пользователей в базе. При необходимости можно использовать SQLAlchemy Core для написания гибких запросов вручную, если нужно работать ближе к SQL.</p><h3>Почему это меняет карьеру</h3><p>SQLAlchemy меняет карьеру <b>Python-разработчика</b> тем, что даёт понимание системной работы с данными, архитектуры приложений и взаимодействия с реальными базами данных. Вы учитесь строить продуманные бэкенды, которые работают с транзакциями, миграциями, связями между таблицами и сложными выборками.</p><p>Знание SQLAlchemy открывает дорогу в мир API, микросервисов и продуктов, где требуется качественное управление данными и гибкая логика работы с БД. Работа с SQL теперь совсем не страшная.</p><h2>10. Seaborn</h2><p>Seaborn — библиотека для визуализации данных на Python, построенная поверх Matplotlib и упрощающая создание информативных и стильных графиков с минимальным количеством кода.</p><p>Она автоматически заботится о красивых стилях, цветах, разметке графиков, легендах и позволяет легко строить распределения, линейные графики, тепловые карты и другие визуализации.</p><p>Библиотека тесно интегрируется с Pandas DataFrame, позволяя использовать колонки данных напрямую для построения графиков, что делает её идеальной для EDA (разведочного анализа данных) и подготовки визуализаций для отчётов и презентаций.</p><h2>Какие задачи решает</h2><p>Визуализация безумно важна, особенно в контексте дата-аналитики. Seaborn отвечает за:</p><ul><li>Быстрое построение информативных графиков для анализа данных и поиска инсайтов;</li><li>Автоматическую обработку ошибок отображения и масштабирования, что экономит время;</li><li>Поддержку сложных визуализаций по типу ящиков с усами или тепловых карт без десятков строк кода;</li><li>Стилизацию графиков без ручных настроек Matplotlib;</li><li>Возможность добавлять статистические элементы (линию регрессии, KDE, распределение);</li><li>Интеграцию с Jupyter Notebook для интерактивного анализа данных.</li></ul><h3>Как пользоваться</h3><p>Допустим, у нас есть датасет с данными о чаевых:</p><p>В три строки мы получаем чистый и читаемый ящик с усами, показывающий, как счет за ужин распределяется по дням недели.</p><p>Для построения более сложных графиков можно использовать диаграмму рассеяния:</p><p>Тут мы добавляем цветовую кодировку по полу, чтобы увидеть зависимости между переменными.</p><h3>Почему это меняет карьеру</h3><p>Seaborn меняет карьеру, потому что даёт навык визуального анализа данных, что критично в современной аналитике и дата-инженерии. Умение быстро строить графики и видеть аномалии, распределения и взаимосвязи между переменными превращает работу с данными из слепого копания в числах в структурный анализ.</p><p>Использование Seaborn в Python-стеке помогает выделиться среди разработчиков, которые ограничиваются Pandas и текстовыми логами, ведь визуализация часто позволяет быстрее заметить закономерности и убедить команду или заказчика в правильности гипотезы.</p><p>Seaborn также учит пониманию данных через визуальные паттерны, что улучшает навыки построения моделей машинного обучения (так понятнее, какие признаки важны), и помогает создавать наглядные отчёты для продуктовых решений, где результат анализа нужно доносить до людей не из айти-индустрии.</p><p><i>А какими библиотеками пользуетесь вы? Делитесь в комментариях!</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Петабайты каждый день: как хранить и использовать данные с умом</title>
      <link>https://tproger.ru/articles/petabajty-kazhdyj-den--kak-hranit-i-ispolzovat-dannye-s-umom</link>
      <comments>https://tproger.ru/articles/petabajty-kazhdyj-den--kak-hranit-i-ispolzovat-dannye-s-umom?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/petabajty-kazhdyj-den--kak-hranit-i-ispolzovat-dannye-s-umom</guid>
      <description><![CDATA[<p> Как компаниям эффективно хранить и масштабировать big data? Разбираем решения с экспертом VK Cloud. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/petabajty-kazhdyj-den--kak-hranit-i-ispolzovat-dannye-s-umom">Петабайты каждый день: как хранить и использовать данные с умом</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[AMD]]></category>
      <category><![CDATA[CSR]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 02 Jul 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Каждый день в мире генерируется более <a href="https://www.techbusinessnews.com.au/blog/402-74-million-terrabytes-of-data-is-created-every-day/">400 миллионов</a> терабайт данных. Возможно, стоило бы отпраздновать эту цифру, но компаниям все сложнее хранить такие объемы. С одной стороны, — это вопрос оптимизации стоимости. С другой, — удобства использования и масштабирования.</p><p>В этом материале вместе со Станиславом Погоржельским, технологическим евангелистом платформы VK Cloud, разберем особенности решений для хранения и работы с большими данными.</p><h2>Особенности локальных хранилищ</h2><p>Стоит держать в уме, что выбор таких решений не всегда зависит от архитектурных принципов и лучших практик, а чаще всего от наличия определенной экспертизы в компании. Проведем очную ставку трех основных моделей построения хранилищ.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-02/7eece396-17d8-49b4-8aca-522d466b3c85.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-02/5c60f581-5f7e-40e2-ac17-65eb3ad59714.png" alt="" /></figure><h3>Семь «грехов» локальных кластеров</h3><p>Теперь поговорим о том, какие неприятные особенности встречаются во время эксплуатации локальных кластеров.</p><h4>Структура данных и хаос</h4><p>В реальных системах данные редко бывают аккуратными. Вместо красивых таблиц разработчик часто сталкивается с миллионами мелких файлов по 1-2 Кб и, например, видео по несколько Гб. Такие крайности требуют противоположных стратегий хранения и кэширования.</p><p>Файловая система, не оптимизированная для работы с малыми файлами, быстро забивается inode'ами (переполнение файловых дескрипторов). Системы хранения начинают задыхаться не от общего объема, а от количества объектов, что критически влияет на производительность. Например, <a href="https://web.archive.org/web/20161101132116/http://engineering.spilgames.com/openstack-swift-lots-small-files/">известны случаи</a>, когда после миллиона объектов OpenStack Swift начинал терять метаданные, а в хранилищах висели призраки удаленных объектов.</p><h4>RAID — не универсальное спасение</h4><p>Настройка RAID-массивов кажется очевидным решением, но не все так однозначно:</p><ul><li>RAID 5 и 6 плохо переносят большие объемы из-за длительного времени восстановления.</li><li>RAID 10 требует удвоения или утроения объема хранения ради скорости и отказоустойчивости.</li><li>На петабайтных объемах пересборка массива после сбоя может занимать больше недели.</li></ul><h4>Поддержка архивов и ZIP-файлов</h4><p>Архивирование данных (например, с помощью ZIP) спасает место, но приводит к другим проблемам: невозможность выборочного доступа к отдельным файлам без полной распаковки, рост времени обработки запросов, сложность мониторинга целостности данных.</p><p>Массовая работа с архивами требует настройки кэширования и часто вынуждает строить параллельные системы для индексации содержимого архивов.</p><h4>Автоматизация мониторинга и ремонта</h4><p>Любая система хранения живет с постоянным риском деградации: умирают диски, выходят из строя контроллеры, падают сети. На уровне сотен и тысяч узлов мониторинг «вручную» невозможен: требуется автоматизированная оркестрация алертов, самовосстановление, динамическая миграция данных на здоровые узлы. Иначе разрастание локальных отказов перерастает в потерю данных.</p><h4>Шардирование данных: неизбежность и боль</h4><p>На больших объемах данных (более 250 Тб) приходится шардировать — разбивать на независимые логические части, чтобы сохранить производительность. Но с шардированием есть проблемы:</p><ul><li>усложняет маршрутизацию запросов;</li><li>увеличивает сложность восстановления данных при сбоях;</li><li>требует отдельных механизмов ребалансировки шардов при добавлении новых узлов.</li></ul><p>Более того, встроенные механизмы шардирования некоторых популярных СУБД (MongoDB, PostgreSQL с партиционированием) не рассчитаны на миллиарды записей и начинают деградировать.</p><h4>Проблемы метаданных</h4><p>Каждый файл и объект требуют метаданных: даты создания, размера, доступа, хеш-суммы. При росте числа объектов метаданные сами по себе становятся огромными: терабайты информации, требующие отдельного хранения, индексирования и защиты.</p><h4>Резервное копирование на практике</h4><p>Бэкап петабайта данных требует продуманной стратегии инкрементальных копий, дедупликации, постоянного тестирования восстановления. Локальное хранение больших объемов данных — это не про покупку железа и развертывание файлового сервера. Это бесконечная инженерная работа по балансировке между скоростью, надежностью, стоимостью и сложностью системы.</p><p>Хранение больших объемов обостряет вопросы производительности, резервного копирования и автоматизации мониторинга, где каждый аспект требует балансировки между скоростью, надежностью и сложностью ИТ-инфраструктуры.</p><h2>Облачные хранилища</h2><p>С локальными хранилищами разобрались, теперь рассмотрим технические особенности альтернативного решения.</p><h3>Гибкость и масштабируемость без ограничений</h3><p>В облаке увеличение объемов хранения происходит мгновенно:</p><ul><li>без ожидания закупки нового оборудования;</li><li>без сложного планирования миграций;</li><li>без перебоев в обслуживании приложений.</li></ul><p>Эксплуатация и разработчики могут динамически добавлять терабайты и петабайты данных в рамках одного API-запроса. Облачное хранилище предлагает готовое решение для масштабирования от стартапов до международного уровня компаний.</p><h3>Финансовая прозрачность и удобная модель оплаты</h3><p>Модель Pay-As-You-Go (оплата по факту использования) дает бизнесу и разработчикам:</p><ul><li>предсказуемость расходов;</li><li>возможность мгновенно адаптировать инфраструктуру под изменяющиеся требования;</li><li>отсутствие необходимости капитальных затрат на старте;</li><li>гибкость в выборе тарифов хранения (горячие, холодные, архивные данные).</li></ul><p>Такая прозрачная модель помогает экономить бюджет без потери качества сервиса.</p><h3>Надежность и отказоустойчивость «из коробки»</h3><p>S3-совместимый Object Storage обеспечивает высокую доступность данных благодаря:</p><ul><li>автоматической репликации данных в нескольких географических регионах;</li><li>встроенным механизмам самовосстановления данных;</li><li>резервированию оборудования на уровне дата-центров;</li><li>постоянному мониторингу целостности объектов.</li></ul><h3>Оптимизация работы с любыми типами данных</h3><p>Хранилище позволяет одинаково эффективно работать:</p><ul><li>с миллионами мелких файлов (фото, документы, логи);</li><li>с тяжелыми объектами (видео или архивами).</li></ul><p>Облачная платформа автоматически оптимизирует хранение и доступ, снижая латентность и ускоряя обработку даже при экстремальных нагрузках.</p><h3>Высокий уровень безопасности данных</h3><p>В облаке предоставляется комплексная защита данных с помощью:</p><ul><li>шифрования на стороне клиента и сервера;</li><li>гибкого управления правами доступа (ACL, IAM);</li><li>соответствия требованиям хранения ПДН и прочих стандартов безопасности;</li><li>автоматического обнаружения потенциальных уязвимостей.</li></ul><p>Безопасность данных обеспечивается на каждом уровне инфраструктуры и подтверждается регулярными внешними аудитами.</p><h3>Инструменты для разработчиков и автоматизации</h3><p>Хранение данных в облаке ориентировано на удобство интеграции и масштабирование за счет:</p><ul><li>полного набора API и SDK для популярных языков программирования;</li><li>готовых модулей для работы с данными в распределенных системах;</li><li>продвинутых средств мониторинга, алертинга и автоскейлинга;</li><li>поддержки DevOps практик через IaC-инструменты.</li></ul><p>Автоматизация всех процессов упрощает разработку и сопровождение проектов, значительно снижая риски человеческих ошибок.</p><h2>Опыт хранения больших данных</h2><p>Когда речь идет о масштабных системах хранения — таких как S3-совместимый сервис Object Storage на платформе VK Cloud, — производительность определяется не только скоростью сети и дисков. Ключевую роль играют архитектурные особенности приложений: как именно данные распределяются, обрабатываются и индексируются.</p><p>Особенно важно это в системах с огромным количеством объектов, где миллионы или миллиарды файлов разного размера постоянно создаются, обновляются и удаляются.</p><h3>Как измеряется производительность облачного хранилища</h3><p>Для реальной оценки производительности облачного хранилища важно замерять:</p><ul><li>Количество операций в секунду (RPS): сколько запросов на чтение/запись способна обработать система.</li><li>Среднюю и 99-ю персентиль задержек: критично для оценки качества обслуживания конечных пользователей.</li><li>Производительность на больших объемах объектов: важно не просто тестировать один файл, а моделировать реальную работу приложений с множеством параллельных операций.</li><li>Влияние мелких и крупных файлов: системы по-разному работают при миллионах маленьких объектов и гигабайтных видео.</li></ul><p>Практические сценарии измерений:</p><ul><li>многопоточная загрузка 100 миллионов объектов размером 1–10 КБ;</li><li>массовое чтение миллионов объектов через S3 API;</li><li>удаление больших объемов объектов для оценки работы сборки мусора;</li><li>сценарии с версионированием объектов, чтобы проверить нагрузку на метаданные.</li></ul><h3>Почему шардирование критически важно для облачного хранилища</h3><p>Правильная организация шардирования данных — один из ключевых факторов производительности больших хранилищ.</p><p><b>Что происходит без правильного шардирования:</b></p><ul><li>«Горячие» бакеты (S3-бакеты) с высокой нагрузкой становятся узким местом.</li><li>Распределение нагрузки по серверам становится неравномерным.</li><li>Метаданные начинают тормозить операции доступа.</li><li>Снижается общая масштабируемость системы.</li></ul><p><b>Реальная практика VK Cloud:</b></p><ul><li>Метаданные объектов распределяются по кластерам через шардирование по диапазонам ключей.</li><li>При превышении нагрузки шард автоматически расщепляется (split) для перераспределения нагрузки между нодами.</li><li>Для хранения метаданных используется Tarantool как высокоскоростная in-memory база данных, способная выдерживать сотни тысяч операций в секунду на один шард.</li></ul><p><b>Такой подход позволяет обеспечить:</b></p><ul><li>низкие задержки доступа даже при миллиардах объектов;</li><li>линейное масштабирование — добавление новых серверов дает реальный прирост пропускной способности;</li><li>быструю обработку как мелких, так и больших файлов без перегрузки одной ноды.</li></ul><p>С увеличением объема метаданных нагрузка на отдельные узлы или компоненты системы возрастает, что ограничивает масштабируемость и может снижать производительность при высоких требованиях к обработке данных.</p><h2>За что мы любим Tarantool</h2><p>Принцип работы СУБД Tarantool кардинально отличается от классических SQL-баз (PostgreSQL, MySQL) в хранилищах:</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-02/15133b4d-c1bc-4d7d-a09f-e86554a1d249.png" alt="" /></figure><p>Tarantool позволяет работать с облачным хранилищем на скорости, которую классические базы не способны обеспечить без радикальных усилий по оптимизации.</p><h2>Как правильно проектировать нагрузку на S3-совместимое облако</h2><p>Если вы проектируете высоконагруженную систему, важно:</p><ul><li>Использовать естественное шардирование ключей (например, вставлять случайные префиксы в имена объектов).</li><li>Ожидать миллионы объектов в бакете и строить приложения так, чтобы они не зависели от скорости листинга всех файлов.</li><li>Минимизировать количество операций массового удаления объектов — использовать batch-удаление через S3 API.</li><li>Понимать, что работа с метаданными так же важна, как и сама передача данных.</li></ul><p>Производительность облачного хранилища определяется не только сетью и железом, но и архитектурой работы с данными. Правильное шардирование, оптимизация структуры ключей и использование быстрых конечных СУБД — основа эффективных и масштабируемых сервисов.</p><h2>Заключение</h2><p>Работа с петабайтными объемами данных требует серьезного подхода к проектированию инфраструктуры. На этом пути локальные решения сталкиваются с проблемами масштабирования, отказоустойчивости, обновления оборудования и обеспечения безопасности. Управление инфраструктурой превращается в отдельный проект со своими ресурсами.</p><p>Облачное хранилище обеспечивает:</p><ul><li>автоматическое масштабирование объема хранения без потерь в производительности;</li><li>высокую доступность данных благодаря распределению по зонам отказа;</li><li>прозрачную модель оплаты — вы платите только за реально используемые ресурсы;</li><li>эффективную работу как с миллионами мелких файлов, так и с крупными объектами;</li><li>безопасность данных с помощью встроенного шифрования и управления доступом через IAM;</li><li>богатый инструментарий API для полной интеграции в любые архитектуры приложений.</li></ul><p>Облачные хранилища предоставляют возможность компаниям сосредоточиться на развитии своих продуктов и бизнес-логики, передав инфраструктурные задачи профессиональной облачной платформе.</p>]]></content:encoded>
    </item>
    <item>
      <title>Эволюция программиста 2005–2025: от CRT-мониторов до квантовых алгоритмов</title>
      <link>https://tproger.ru/articles/evolyuciya-programmista-2005-2025--ot-crt-monitorov-do-kvantovyh-algoritmov</link>
      <comments>https://tproger.ru/articles/evolyuciya-programmista-2005-2025--ot-crt-monitorov-do-kvantovyh-algoritmov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/evolyuciya-programmista-2005-2025--ot-crt-monitorov-do-kvantovyh-algoritmov</guid>
      <description><![CDATA[<p>Эпохи развития программирования в России и в мире. Какие стадии прошли разработчики и к чему пришли в настоящий момент. Прогнозы на будущее. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/evolyuciya-programmista-2005-2025--ot-crt-monitorov-do-kvantovyh-algoritmov">Эволюция программиста 2005–2025: от CRT-мониторов до квантовых алгоритмов</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Обучение программированию]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Stack Overflow]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[jQuery]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Ruby on Rails]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[macOS]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[Mozilla]]></category>
      <category><![CDATA[WebAssembly]]></category>
      <category><![CDATA[Образование]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Soft Skills]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Обучающие курсы]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Fullstack]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 25 Jun 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>За последние 20 лет программирование изменилось до неузнаваемости. Если в 2005 году разработчики писали код на PHP 4.0 под мерцание CRT-экранов, то в 2025-м нейросети помогают им генерировать целые модули, а квантовые компьютеры становятся частью исследовательских проектов.</p><p>Эта статья — подробная хроника эволюции программистов: какие языки и технологии они осваивали, как менялись их рабочие места, методы обучения и даже само восприятие профессии. Мы разберем ключевые этапы, от первых веб-гигантов до эпохи совместного программирования с ИИ, и попробуем представить, что ждет нас дальше.</p><h2>2005-2009: Эпоха авторских решений и первых веб-фреймворков</h2><p>В середине 2000-х типичный рабочий инструмент программиста — это громоздкий системный блок с процессором Intel Pentium 4 или новеньким Core 2 Duo. Мониторы с ЭЛТ-трубкой постепенно уступали место LCD-экранам с разрешением 1024×768 — именно на таких дисплеях создавались первые версии Wikipedia и набирающих популярность соцсетей. Оперативная память в 1-2 ГБ считалась нормой, а жесткие диски на 80-160 ГБ часто заполнялись до отказа — проекты редко весили меньше нескольких гигабайт.</p><p>Серьезная разработка велась преимущественно на стационарных компьютерах. Ноутбуки только начинали входить в обиход — их брали в офис, но для реальной работы предпочитали мощные десктопы. Операционная система Windows XP доминировала на рабочих станциях, в то время как серверы чаще всего крутили на Linux — Red Hat Enterprise или Debian.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-13/d5fca723-5450-4b72-8e8d-4cd57627fb99.jpg" alt="" /></figure><p>Среды разработки того времени сегодня кажутся архаичными. Eclipse и NetBeans потребляли гигабайты памяти, Visual Studio 2005 требовала серьезных ресурсов. Многие разработчики предпочитали простые текстовые редакторы вроде Notepad++, а для отладки использовали примитивные методы вроде вывода значений переменных через print. Контроль версий только начинал входить в практику — Git появился в 2005 году, но большинство команд продолжали использовать SVN или вообще заливали файлы по FTP напрямую на продакшен.</p><p>Языковая экосистема этого периода вращалась вокруг трех основных технологий. PHP версий 4 и 4.3 доминировал в веб-разработке — на нем работало около 80% всех сайтов в интернете. Однако его объектно-ориентированные возможности были крайне ограничены до выхода PHP 5 в 2004 году.</p><p>Java в лице J2EE оставалась стандартом для корпоративных решений — банковских систем, крупных порталов и ERP-комплексов. Spring Framework только начинал набирать популярность, а Hibernate упрощал работу с реляционными базами данных. C++ сохранял свои позиции в разработке игр (особенно с использованием Unreal Engine), драйверов и высоконагруженных сервисов.</p><p>Фронтенд-разработка в те годы была невероятно простой по современным меркам. Верстали преимущественно таблицами, а всю динамику реализовывали через jQuery, который появился в 2006 году и быстро вытеснил нативный JavaScript из повседневной практики. AJAX-запросы казались революционной технологией, позволяющей обновлять части страницы без ее полной перезагрузки.</p><p>Обучение программированию в этот период кардинально отличалось от современных подходов. Онлайн-курсы практически отсутствовали. Основными источниками знаний служили бумажные книги:</p><ul><li>«Философия Java» Брюса Эккеля;</li><li>«Совершенный код» Стива Макконнелла;</li><li>«PHP и MySQL. Разработка веб-приложений» Люка Веллинга.</li></ul><p>Русскоязычное сообщество активно обсуждало вопросы разработки на форумах RSDN.ru и CyberForum.ru. В 2008 году появился Stack Overflow, который постепенно стал главной площадкой для профессиональных обсуждений.</p><p>Университетское образование давало хорошую теоретическую базу — алгоритмы, структуры данных, принципы ООП. Однако практическим навыкам приходилось учиться самостоятельно, методом проб и ошибок. Документацию часто скачивали в формате CHM-файлов или читали непосредственно на сайтах вроде php.net и MSDN.</p><p>Типичный стек начинающего разработчика в 2009 году:</p><ul><li>HTML/CSS с jQuery для фронтенда;</li><li>PHP или Ruby on Rails для бэкенда;</li><li>MySQL в качестве базы данных.</li></ul><p>ORM-технологии еще не получили широкого распространения, поэтому SQL-запросы писали вручную. Многие проекты представляли собой монолитные приложения, где весь код хранился в единой кодовой базе без четкого разделения на модули.</p><p><b>Показательный кейс</b>:</p><p>В 2007 году разработчик PHP-приложений из МЭСИ (Москва) столкнулся с типичной для того времени проблемой — SQL-инъекциями. Вместо стандартных решений он создал DLAC (Data Logic Access Component) — обертку для работы с базой данных, которая автоматически экранировала параметры запросов. Это выглядело революционно на фоне типичного кода того периода, где строки запросов часто собирали через конкатенацию с пользовательским вводом.</p><p>Компонент использовал новую для 2005 года технологию Generics в C#. Он генерировал параметризованные запросы, что резко снижало риски взлома.</p><p><i>Разработчики в университетской среде тогда редко задумывались о безопасности — многие проекты содержали уязвимости вроде  </i>SELECT * FROM users WHERE name = ‘.$_POST[‘name’]<i>. </i></p><p><i>DLAC стал локальным спасением для внутренних систем МЭСИ, пока в 2009 году не появился NHibernate — порт популярного Java-фреймворка Hibernate.</i></p><p>Этот кейс хорошо иллюстрирует дух эпохи: отсутствие готовых безопасных решений заставляло программистов изобретать велосипеды. Многие подобные наработки позже легли в основу ORM-библиотек, но тогда они рождались в муках — через пробелы в безопасности и километры самописного кода.</p><h2>2010-2014: Мобильная революция и рассвет JavaScript</h2><p>Начало нового десятилетия ознаменовалось стремительным ростом мобильных технологий. Выход iPhone 4 в 2010 году и Android 2.3 Gingerbread задал новые стандарты мобильной разработки.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-13/7b640694-b2cd-4f03-a68f-51ed138557b2.jpg" alt="" /></figure><p>Программисты массово переходили на MacBook Pro — не столько из-за преимуществ macOS, сколько благодаря появлению Retina-дисплеев в 2012 году, которые кардинально улучшили качество отображения кода.</p><p>Железо продолжало стремительно эволюционировать. Твердотельные накопители (SSD) начали вытеснять традиционные жесткие диски в рабочих станциях. Облачные платформы вроде AWS и Heroku стали реальной альтернативой локальным серверам, которые раньше часто стояли прямо под рабочими столами в офисах. Оперативная память в 8 ГБ стала стандартом для комфортной разработки, а четырехъядерные процессоры ускорили сборку крупных проектов.</p><p>Языковая палитра этого периода значительно расширилась. Objective-C стал основным языком для iOS-разработки и оставался таковым до появления Swift в 2014 году. Python 3 начал набирать популярность благодаря веб-фреймворку Django и научным библиотекам NumPy и Pandas, которые открыли дорогу для анализа данных в массовом сегменте.</p><p>JavaScript пережил настоящий ренессанс — после выхода AngularJS в 2010 и Node.js в 2009 году он перестал быть просто «языком для анимаций на сайте», превратившись в полноценную платформу для fullstack-разработки.</p><p><b>Важный факт</b>. В 2011 году разработчик из Сан-Франциско Райан Даль представил Node.js — среду выполнения JavaScript на стороне сервера. За первые 24 часа после релиза проект собрал 10 000 звезд на GitHub, что для того времени стало рекордом. Многие скептически относились к идее использовать JavaScript вне браузера, но уже через год такие компании как LinkedIn и Walmart перевели части своего бэкенда на Node.js, получив прирост производительности в 2-3 раза по сравнению с традиционными решениями на Java и Ruby.</p><p>Образовательная сфера претерпела значительные изменения. В 2011 году запустилась Coursera с первым массовым курсом по программированию — Machine Learning от Эндрю Ына. В 2012 году в Кремниевой долине открылся Hack Reactor, ставший прототипом современных coding bootcamps (интенсивов по программированию). Эти форматы предложили альтернативу традиционному университетскому образованию, сделав акцент на практических навыках.</p><p>Параллельно в России:</p><ul><li>В 2012 году появился Hexlet — одна из первых русскоязычных платформ с практико-ориентированными курсами по программированию. Особенность: выполнение заданий в реальной среде разработки через браузер. Платформа до сих пор работает: на текущий момент 80% выпускников трудоустраиваются в IT, <a href="https://ru.hexlet.io/blog/posts/hse-research">согласно исследованию ВШЭ</a>. В 2012 этот показатель был еще выше.</li><li>«Нетология» (основана в 2011) к 2013 году запустила курсы по веб-разработке с акцентом на JavaScript и Python, сотрудничая с российскими tech-компаниями. Их модель включала менторство и проектные работы.</li><li>В 2013 году стартовал Stepik — платформа с открытыми курсами от ведущих вузов (ИТМО, МФТИ). Особенность: интерактивные задачи с автоматической проверкой кода, что было прорывом для местного рынка.</li></ul><p>Курс «Введение в Linux» от Stepik (2014) за полгода собрал 50 тыс. студентов — рекорд для Рунета. Задания включали настройку виртуальных серверов, что сразу применялось в работе.</p><p>Эти проекты заложили основу для бума EdTech в России после 2015 года, доказав, что онлайн-формат может давать актуальные навыки быстрее вузов.</p><p>Типичный разработчик среднего уровня в 2014 году:</p><ul><li>понимал принципы REST API;</li><li>начинал осваивать основы DevOps с появлением Docker в 2013;</li><li>экспериментировал с микроконтроллерами вроде Arduino или Raspberry Pi, создавая собственные IoT-устройства.</li></ul><p>В профессиональной среде начал формироваться консенсус о том, что PHP устаревает для сложных коммерческих проектов.</p><h2>2015-2019: Эра больших данных и облачных технологий</h2><p>Аппаратные возможности сделали очередной рывок вперед. Многоядерные процессоры Intel i7 и AMD Ryzen стали стандартом для рабочих станций. 16 ГБ оперативной памяти перестали быть роскошью, а мониторы с разрешением 4К стали доступны широкому кругу разработчиков. В 2015 году появился Visual Studio Code, который быстро обогнал по популярности Sublime Text и Atom благодаря удачному сочетанию функциональности и производительности.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-13/c92b70be-b3eb-4924-a40a-587ed3d43592.png" alt="" /></figure><p>Языковая экосистема продолжила развитие. TypeScript, представленный в 2014 году, предложил решение проблемы масштабируемости JavaScript-кода в крупных проектах. Go от Google, созданный еще в 2009, нашел свою нишу в разработке микросервисов и инструментов оркестрации вроде Kubernetes (2015). Rust от Mozilla начал завоевывать доверие системных программистов благодаря уникальной системе владения памятью.</p><p>JavaScript-сообщество столкнулось с первыми серьезными проблемами. В 2016 году инцидент с пакетом left-pad показал уязвимость экосистемы npm — удаление одного небольшого модуля привело к сбоям в работе тысяч проектов по всему миру. Это заставило разработчиков задуматься о зависимости от сторонних библиотек.</p><p>Типичный senior-разработчик в 2019:</p><ul><li>разбирался в микросервисной архитектуре и понимал, как избежать vendor lock-in (привязки к поставщику) при работе с облачными провайдерами;</li><li>имел опыт работы с React или <a href="http://vue.js">Vue.js</a>;</li><li>знал, что понимание принципов работы алгоритмов становится менее важным, чем развитие soft skills для работы в команде.</li></ul><p>Ключевые технологии этого периода включали Kubernetes, который стал стандартом де-факто для оркестрации контейнеров, а также TensorFlow (2015) и PyTorch (2016), открывшие эру машинного обучения для широкого круга разработчиков. Появились первые серьезные инструменты для работы с большими данными — Apache Spark, Hadoop.</p><p><i>Ключевой момент. В 2016 году Netflix раскрыл детали своего перехода на облачную инфраструктуру AWS. Компания полностью перенесла все сервисы — от рекомендательной системы до биллинга — в облако за семь лет. Главным триггером стала катастрофа 2008 года, когда три дня простоя дата-центра оставили 8,4 млн подписчиков без доступа к сервису. Миграция потребовала перепроектирования архитектуры: инженеры разбили монолит на 500 микросервисов и внедрили Chaos Monkey — инструмент для тестирования отказоустойчивости, который случайно отключал серверы в продакшене.</i></p><p>Этот кейс стал хрестоматийным примером cloud-native подхода. Облачные технологии стали активно использоваться в разработке, а обращение с ними — обязательным навыком для прогеров.</p><h2>2020-2024: AI-assisted разработка и новые парадигмы</h2><p>Пандемия COVID-19 ускорила переход на удаленную работу. Программисты по достоинству оценили макбуки на чипах M1 (2020) за их энергоэффективность и производительность. Домашние офисы оснащались 32-дюймовыми 4К-мониторами и механическими клавиатурами, ставшими своеобразным профессиональным стандартом.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-13/65ba41e0-844c-419f-8656-e78905e93540.jpg" alt="" /></figure><p>Языковая палитра продолжала обогащаться. Rust официально вошел в ядро Linux в 2022 году, подтвердив свой статус системного языка нового поколения. Zig появился как современная альтернатива «C» с акцентом на безопасность. WebAssembly (Wasm) позволил запускать ресурсоемкие приложения прямо в браузере, открыв новые возможности для веб-разработки.</p><p>Искусственный интеллект начал проникать в повседневную работу программистов. GitHub Copilot на базе GPT-3, представленный в 2021, изменил сам процесс написания кода, предлагая контекстные подсказки. Low-code платформы вроде Retool упростили создание внутренних инструментов для бизнеса.</p><p>Типичный lead-разработчик в 2024 году:</p><ul><li>умел эффективно работать в гибридных командах (офис + удаленка);</li><li>автоматизировал рутинные задачи через ChatGPT API;</li><li>следил за развитием квантовых вычислений, хотя практическое применение пока оставалось ограниченным.</li></ul><p><i>Ключевой момент. В 2023 году GitHub Copilot, разработанный совместно с OpenAI, стал катализатором перемен в индустрии. За первый год после релиза инструмент использовали более 1,3 млн разработчиков — каждый десятый подписчик GitHub. Система анализировала контекст кода и предлагала целые функции: например, при написании SQL-запроса она автоматически генерировала соответствующую модель данных на Python. Amazon внедрил аналогичный инструмент Amazon Q Developer для внутренних команд — по заявлению CEO Энди Джесси, это сэкономило компании 4,500 человеко-лет работы и $260 млн ежегодно.</i></p><p><i>Но были и курьезы. В 2024 году разработчик из Берлина случайно отправил в продакшен код, полностью сгенерированный Copilot. Система использовала фрагмент из GPL-лицензированной библиотеки, что нарушило политику компании по открытому ПО. Инцидент заставил пересмотреть процессы ревью: теперь 78% команд требуют ручной проверки AI-кода перед мержем (слиянием).</i></p><p><i>Параллельно выяснилось, что Copilot в 40% случаев предлагает уязвимый код при работе с СУБД — это привело к взлому API стартапа через SQL-инъекцию. Такие кейсы показали, что ИИ пока не заменяет программистов, а требует от них новых навыков — критического анализа машинных предложений и понимания юридических аспектов кода.</i></p><h2>2025: Современное состояние профессии</h2><p>Современные рабочие станции программистов оснащены ноутбуками с процессорами Apple M4 (3 нм) или Windows-машинами на Snapdragon X Elite. Мониторы с разрешением 8К используются для разработки AR-приложений, а OLED-экраны с HDR стали стандартом для работы с графикой. Появляются первые экспериментальные IDE с нейроинтерфейсами, способные предсказывать код на основе анализа мозговой активности.</p><p>Среди языков программирования выделяется Mojo (2023) — «Python для GPU», набирающий популярность в сфере машинного обучения. Carbon как потенциальный наследник C++ пока остается в тени Rust. Квантовые языки вроде Q# и Cirq интересуют в основном энтузиастов и исследователей.</p><p>Профессия претерпела значительные изменения. ИИ стал не конкурентом, а помощником — по некоторым оценкам, около 60% рутинного кода в 2025 году (тесты, документация) генерируется автоматически. Знание английского языка стало важнее знания сложных алгоритмов — без него невозможно эффективно работать с современными AI-инструментами. Понятие «fullstack-разработчик» трансформировалось — теперь оно подразумевает владение фронтендом, одним бэкенд-языком и основами машинного обучения.</p><p>За два десятилетия программисты прошли путь от одиночек за CRT-мониторами до участников глобальных распределенных команд. Если в 2005 ключевым навыком было умение написать работающий код, то в 2025 главное — способность эффективно взаимодействовать с ИИ-ассистентами. Однако основы профессии остались неизменными — логическое мышление, способность к абстракции и желание автоматизировать рутинные задачи.</p><p>Будущее обещает новые трансформации. К 2030 году нейроинтерфейсы смогут заменить традиционные устройства ввода, а квантовые компьютеры — перевернуть основы криптографии. Но пока актуальными остаются проверенные временем принципы: изучать перспективные технологии (вроде Rust и Mojo), осваивать работу с ИИ и, конечно, совершенствовать главный навык любого программиста — умение быстро и грамотно гуглить.</p><p>Ты уже программист, если читаешь это! Больше о кодинге <a href="https://t.me/+ezugB7gnIEsxNGMy">тут</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как сделать свой первый сайт на HTML и CSS: пошаговая инструкция</title>
      <link>https://tproger.ru/articles/kak-sdelat-svoj-pervyj-sajt-na-html-i-css--powagovaya-instrukciya</link>
      <comments>https://tproger.ru/articles/kak-sdelat-svoj-pervyj-sajt-na-html-i-css--powagovaya-instrukciya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-sdelat-svoj-pervyj-sajt-na-html-i-css--powagovaya-instrukciya</guid>
      <description><![CDATA[<p>Как сделать на HTML и CSS. Показываем, какими навыками нужно обладать для создания сайтов. Рассматриваем пошаговую инструкцию и основные нюансы ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-sdelat-svoj-pervyj-sajt-na-html-i-css--powagovaya-instrukciya">Как сделать свой первый сайт на HTML и CSS: пошаговая инструкция</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[WordPress]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 23 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Tilda, Wix, WordPress — конструкторы сайтов кажутся простым решением. Согласны, на готовых блоках можно сделать интернет-магазин за 1 час. Но учтите, что в конструкторе непонятно, как всё работает изнутри. Вы не поймёте, почему сайт долго грузится, как увеличить кнопку для смартфонов и т. д.</p><p><b>Выбрали путь программиста</b>? Значит навсегда запомните, когда опубликовали первый самописный сайт. Откосить не получится: мы сразу перейдём к практике — к концу статьи у вас будет ссылка на сайт-визитку.</p><p><b>Мало времени</b>? Выделите 10 минут — мы используем только HTML и CSS.</p><p>Вы узнаете:</p><ul><li>как подключать стили,</li><li>как верстать блоки,</li><li>как опубликовать сайт.</li></ul><p>Возможно сейчас вы убедитесь, что веб-разработка — это ваше призвание, и захотите продолжить обучение профессии.</p><h2>Шаг 1. Подготовим инструменты и папку проекта</h2><p>Сайт можно писать и в блокноте. Это как забивать гвозди камнем – работает, но зачем мучиться? <b>Редактор кода подсвечивает синтаксис, подсказывает команды и сразу указывает на ошибки</b>.</p><p>Новичкам рекомендуем ставить <b>Visual Studio Code (VS Code)</b>. Он бесплатный, не тормозит и понимает любой код. Плюс у него огромное сообщество — если нужно установить плагин или увеличить шрифт, ответ на вопрос уже есть в интернете.</p><p><a href="https://code.visualstudio.com/download">Скачайте VS Code с официального сайта</a>.</p><h2>Как устроен веб-проект</h2><p><b>Сайт</b> — это папка с файлами для браузера.</p><p>HTML-файл содержит текст и разметку страницы, CSS-файл — правила оформления. Браузер берёт эти два файла и показывает веб-страницу.</p><p>Основной файл сайта обычно называют <i>index.html</i>. Стили хранятся в <i>style.css</i>.</p><p>Кроме файлов HTML и CSS, в нашем проекте будут папки:</p><ul><li><i>img </i>— для картинок.</li><li><i>fonts </i>— для шрифтов.</li></ul><p><b>Создайте на рабочем столе папку с названием сайта</b>, например <i>first-site</i>, и соберите начальную структуру — это займёт 1 минуту.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/5ba1fa76-6d96-4b7b-aac4-633a4d251a7e.jpg" alt="" /><figcaption>Типичная структура веб-проекта</figcaption></figure><h2>Шаг 2. Создадим базовую HTML-страницу</h2><p>В VS Code есть удобная фишка: наберите символ «!» и нажмите Tab. Редактор <b>автоматически </b>создаст базовую структуру HTML-документа.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/3fbcd34e-cf7c-473c-b0cf-84260e9aa42c.jpg" alt="" /><figcaption>Структура HTML-документа в VS Code</figcaption></figure><p>Как читать структуру:</p><ul><li><i></i><b>&lt;!DOCTYPE html&gt; </b>—<b> </b>сообщает браузеру, что это HTML-документ.</li><li><i></i><b>&lt;html&gt; </b>—<b> </b>корневой элемент, внутри которого живёт страница.</li><li><i></i><b>&lt;head&gt; </b>—<b> </b>служебная информация, которую не видно на странице.</li><li><i></i><b>&lt;body&gt; </b>—<b> </b>то, что увидят пользователи на странице.</li></ul><p><b>Измените Document на название вашего сайта</b> — это текст, который появится во вкладке браузера.</p><p>Добавим контент в &lt;body&gt;:</p><p>Мы не комментируем каждый тег и атрибут, потому что это тема для отдельной статьи. Наша задача — показать, как быстро собрать сайт и выложить его в интернет.</p><p><b>Сохраните HTML-файл и откройте его в браузере</b>. Поздравляем, ваша первая веб-страница готова! Она недоступна другим пользователям, но мы это исправим.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/c3588fae-fe59-447a-9045-d7f7ada0161c.jpg" alt="" /><figcaption>HTML-страница без стилей</figcaption></figure><h2>Шаг 3. Подключим стили CSS</h2><p>Сейчас сайт выглядит странно — чёрный текст на белом фоне. Так не пойдёт, добавим стилей в файле <i>style.css</i>.</p><p>CSS можно писать внутри HTML или в отдельном файле. Мы выберем второй вариант, потому что это удобнее.</p><p>Подключим CSS к HTML. В секции <i></i> вашего <i>index.html</i> добавьте строчку:</p><p>Тег <i> </i>говорит браузеру: «Возьми файл <i>style.css</i> из той же папки и примени все стили к этой странице».</p><p>Добавьте в <i>style.css </i>первое правило:</p><p><b>Сохраните оба файла </b>—<b> HTML и CSS</b>. Обновите страницу в браузере.</p><p>Фон поменял цвет? Значит, CSS подключён правильно. Можете вернуть белый фон или оставить голубой — далее мы добавим более интересные стили.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/95a0bd53-c4a5-4139-92c5-1c1fdda3916b.jpg" alt="" /><figcaption>Применили стиль к фону страницы</figcaption></figure><h2>Шаг 4. Подключим шрифты</h2><p>Есть три способа избавиться от дефолтного Times New Roman:</p><ul><li>Google Fonts — бесплатная библиотека шрифтов от Google.</li><li>Локальные файлы — загружаете шрифт на свой сервер.</li><li>Системные шрифты — используете то, что уже есть на компьютере пользователя.</li></ul><p><b>Для первого сайта на HTML и CSS рекомендуем Google Fonts</b> — это просто, быстро и надёжно.</p><p>Перейдите на <a href="http://fonts.google.com">fonts.google.com</a> и выберите шрифт. Популярные варианты: Roboto, Open Sans, Lato, Montserrat. Нажмите на понравившийся шрифт, выберите начертания (тонкий, обычный или жирный), скопируйте код подключения и вставьте в <i>head</i>.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/19c3409f-ea46-42fb-a56d-2680820d1fb3.jpg" alt="" /><figcaption>Подключение всех начертаний Montserrat в Google Fonts</figcaption></figure><p>На Google Font собраны популярные шрифты. Если этого мало, нужно скачать шрифт (.woff, .woff2, .ttf) и поместить в папку fonts.</p><p>Путь к файлу указывается относительно CSS-файла. Подключаем начертания через <i>@font-face:</i></p><p>Теперь используйте шрифт в CSS:</p><p>Для каждого начертания (обычный, жирный, курсив) нужно отдельное правило <i>@font-face</i>.</p><h2>Шаг 5. Сверстаем блоки</h2><p>Замените содержимое вашего <i>style.css</i> на этот код:</p><p>Что мы делаем:</p><ul><li>Убираем стандартные отступы браузера и задаём голубой фон.</li><li>Центрируем карточку по всей странице с помощью flexbox.</li><li>Создаём белую карточку с тенью и скруглёнными углами.</li><li>Делаем круглый аватар с рамкой.</li><li>Стилизуем текст и кнопку.</li><li>Добавляем эффект при наведении на кнопку.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/d89d9cf8-b178-4794-bd56-00997cf45750.jpg" alt="" /><figcaption>Простая визитка на HTML и CSS с анимированной кнопкой и ссылкой на Телеграм</figcaption></figure><h2>Шаг 6. Загрузим сайт на хостинг</h2><p>Чтобы визиткой можно было поделиться, нужно загрузить файлы на <b>хостинг</b>. Это сервер, который работает круглосуточно и показывает ваш сайт всем желающим. Посмотреть, как это работает, можно на бесплатном тарифе.</p><p>Заходим на сайт хостинга (Beget, Hostiman, InfinityFree) и регистрируемся. После подтверждения email вы попадёте в панель управления. Система предложит выбрать домен — берите бесплатный типа название.<b>fwh.is</b>.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/26a6c762-28f6-4c16-9db2-9963b1468a14.jpg" alt="" /><figcaption>Выбор бесплатного поддомена на InfinityFree</figcaption></figure><h2>Загружаем файлы на сервер</h2><p>После создания аккаунта появится доступ к файловому менеджеру. Через веб-интерфейс можно управлять файлами на сервере прямо из браузера. Перейдите в папку <i>htdocs </i>— это корневая директория вашего сайта, куда нужно загружать структуру.</p><p>Удалите лишние файлы по типу <i>default.php</i> и загрузите ваши файлы: <i>index.html</i>, <i>style.css</i>,  <i>папки img и fonts</i>. Основной <i>index.html </i>должен лежать прямо в <i>htdocs</i>, а не во вложенной папке — иначе сайт не откроется.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/142fed8d-33ff-4d1a-bc2c-0bb97effdbb8.jpg" alt="" /><figcaption>Менеджер файлов InfinityFree</figcaption></figure><p>Более продвинутый способ — использовать FTP-клиент <a href="https://filezilla-project.org/">FileZilla</a>. В панели хостинга найдите FTP-данные и подключитесь через программу. Это удобнее для больших проектов, но для первого сайта веб-менеджера будет достаточно.</p><h2>Проверяем результат</h2><p>Через несколько минут после загрузки ваш сайт будет доступен по адресу. Откройте его в браузере — если всё сделано правильно, увидите свою страницу. Если что-то не работает, проверьте, что <i>index.html</i> лежит в корне <i>htdocs</i>, а <i>style.css</i> загружен в ту же папку.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/28368cd4-887b-41fe-8930-37b51e3875e2.jpg" alt="" /><figcaption>Опубликованная визитка на HTML и CSS</figcaption></figure><h2>Реальность бесплатного хостинга</h2><p>Для изучения основ и создания первых проектов на HTML и CSS это отличный вариант. Регистрация занимает 1 минуту, никаких настроек, можно сразу экспериментировать и видеть результат.</p><p><b>Помните про обратную сторону медали</b>. Бесплатные хостинги жёстко ограничивают ресурсы — трафик, место на диске, нагрузку на сервер. Иногда вставляют рекламу на ваш сайт. Серверы часто «падают» — страница может быть недоступна по несколько часов.</p><p>Самая большая проблема — нестабильность бизнеса. Бесплатные хостинги закрываются без предупреждения. Сегодня ваш сайт работает, а завтра компания решила, что бесплатные услуги больше не окупаются.</p><p>Скрытые ограничения:</p><ul><li>В рекламе бесплатные хостинги обещают безлимитный трафик и неограниченное место, но вынуждают переходить на платный тариф после 100 посетителей в день.</li><li>Про индексацию можно забыть — поисковые системы не пропустят бесплатные поддомены на первые страницы выдачи.</li><li>На бесплатных хостингах слабая защита. Ваш сайт могут использовать для размещения вредоносного кода, а вы об этом даже не узнаете.</li></ul><h2>Когда стоит переходить на платный хостинг</h2><p>Бесплатный хостинг — это тренировочная площадка, а не постоянное решение. Если планируете заниматься веб-разработкой, создавать портфолио или коммерческие проекты, лучше сразу инвестировать в качественный хостинг и собственный домен.</p><p>Самый простой домен стоит 200-1000 рублей/год, а базовый хостинг — 100-300 рублей/месяц. Плюс получите доступ к технологиям (PHP, MySQL), более стабильную работу и нормальную техподдержку. <b>Начните с минимального тарифа </b>— <b>его хватит на тренировочные проекты, а потом можно масштабироваться</b>.</p><h2>Куда двигаться дальше?</h2><p>Мы создали первый сайт и опубликовали его в интернете. Если повторяли за нами то поздравляем — многие останавливаются на теории, а вы дошли до результата. Теперь у вас есть понимание основ:</p><ul><li>как работает HTML,</li><li>зачем нужен CSS,</li><li>что такое хостинг и домен.</li></ul><p><b>Следующий шаг</b> — подробнее изучить CSS. Сайт-визитка из примера нормально отображается только на больших экранах. Однако 60% пользователей <a href="https://gs.statcounter.com/platform-market-share/desktop-mobile-tablet">заходит</a> с телефонов. Изучите медиазапросы, они применяются только на определённых размерах дисплея.</p><p>Подробнее про адаптив рассказал старший фронтенд-разработчик Никита Кушнарёв: <a href="https://tproger.ru/articles/esli-vy-umeete-pokrasit-knopochku-no-hotite-uznat-bolshe-o-vjorstke-veb-prilozhenij">Если вы умеете покрасить кнопочку, но хотите узнать больше о вёрстке веб-приложений</a>.</p><p>Попробуйте переделать карточку так, чтобы она нормально выглядела на телефоне. Уменьшите размеры, измените отступы, сделайте кнопку на всю ширину. Потом изучите <a href="https://tproger.ru/articles/css-grid-i-flexbox--evolyuciya-maketov-v-veb-dizajne">Flexbox и CSS Grid</a> — современные способы вёрстки макетов.</p><p>Когда почувствуете уверенность в CSS, пора знакомиться с <b>JavaScript</b>. Это язык программирования, который делает сайты интерактивными. Сложные анимации, всплывающие окна, динамическое изменение контента — это JS. Предупреждаем, он сложнее HTML и CSS. В нём есть функции, условия, циклы — всё то, что пугает новичков.</p><p>Подробнее про JavaScript: <a href="https://tproger.ru/articles/javascript-s-nulja-dorozhnaja-karta">Разработка на JavaScript с нуля: дорожная карта</a>.</p><p><b>Изучайте инструменты разработчика</b> в браузере. Нажмите F12 на любом сайте — откроется интерфейс для просмотра структуры сайта, отладки JS, тестирования адаптива. Смотрите, как устроены другие сайты, изучайте чужой код.</p><p>Самое время узнать о большем количестве инструментов программиста. Читайте в нашем <a href="https://t.me/+N9AAs1a82VA1MDMy">тг-канале!</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Как работает Sharding в базах данных?</title>
      <link>https://tproger.ru/articles/kak-rabotaet-sharding-v-bazah-dannyh-</link>
      <comments>https://tproger.ru/articles/kak-rabotaet-sharding-v-bazah-dannyh-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Владислав Устинов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-rabotaet-sharding-v-bazah-dannyh-</guid>
      <description><![CDATA[<p>Что такое Sharding. Показываем, как работает шардинг в базах данных. Рассматриваем пошаговую инструкцию и основные нюансы ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-rabotaet-sharding-v-bazah-dannyh-">Как работает Sharding в базах данных?</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[NoSQL]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 15 May 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Когда данных становится слишком много для одного сервера, на помощь приходит шардинг — способ разбить базу на части и разложить их по разным машинам. Это помогает масштабироваться, ускоряет запросы и снижает нагрузку. Но вместе с плюсами шардинг приносит и новые сложности: как искать данные, как проводить транзакции между серверами, как считать агрегаты. Сегодня разбираемся, как всё устроено, какие бывают подходы к шардингу и что нужно учесть при его внедрении.</p><h2>Как работает database sharding</h2><p>Database sharding (шардирование базы данных) — это техника горизонтального масштабирования, при которой большая база разделяется на несколько частей. Их называют шардами. Эти шарды распределяются по другим серверам и связываются в одну систему. Рассмотрим подробнее.</p><h3>Принцип: разбиение данных на независимые сегменты (шарды)</h3><p>Каждый шард работает как отдельная независимая база данных. Ключевым элементом здесь выступает ключ шардирования (shard key). Это правила, которые определяют, в какой именно шард попадёт конкретная строка данных.</p><p>Например, мы можем задать правило: если у нас есть user_id и его значение меньше тысячи, то данные попадают в шард 1, если значение больше тысячи, то в шард 2.</p><p>Главная цель такого разделения — добиться независимости шардов. В идеале запрос, касающийся данных одного пользователя (или одного документа, заказа и т. д.), должен обрабатываться только одним шардом.</p><p>Так, мы можем параллельно обрабатывать много запросов и увеличивать пропускную способность системы.</p><h3>Общая архитектура: клиент — роутер — шард</h3><p>Чтобы приложение могло понять, в какой шард отправить запрос, нужна особая архитектура.</p><p><b>Клиент</b>: Программа на стороне пользователя, которая отправляет стандартный запрос к базе данных (например, SELECT * FROM users WHERE user_id = 123).</p><p><b>Маршрутизатор запросов</b> или роутер (Query Router): Это что-то вроде посредника между клиентом и шардом, который выполняет роль диспетчера. Он принимает запрос, при помощи sharding ключа определяет, что это за данные, в какой шард и с какой целью их надо отправить. Далее он отправляет запрос на нужный шард.</p><p><b>Шард (Shard)</b>: Получает запрос, выполняет и возвращает результат обратно маршрутизатору, который затем передаёт его клиенту.</p><p>Благодаря такой архитектуре мы можем «скрыть» database sharding на стороне клиента и обеспечить централизованное управление запросами. Не надо сильно заморачиваться с кодом и архитектурой приложений, ведь вся логика будет на серверах.</p><h3>Основные компоненты: шард, маршрутизатор, реплика-сеты</h3><p>Мы уже рассмотрели, что такое шарды и маршрутизаторы, теперь обратим внимание на реплика-сеты. Это сервера с копией данных шардов. Если главный сервер шарда выходит из строя, одна из реплик автоматически берёт на себя его роль. Так, мы можем повысить отказоустойчивость нашей системы.</p><p>Ещё в этой схеме обычно применяют серверы конфигурации. Это отдельный компонент, который хранит метаданные о шардах. Он содержит информацию о том, какие диапазоны ключей или хеши какому шарду соответствуют. Маршрутизаторы периодически обращаются к серверам конфигурации, чтобы получить актуальную карту распределения данных и лучше понять, в какой шард направить тот или иной запрос.</p><h2>Виды шардинга</h2><p>Существует много вариантов, как разбить базу данных на шарды. Этот выбор будет зависеть от множества факторов: структуры данных, типичных запросов, требований к производительности и сложности управления. Разберём основные виды шардинга.</p><h3>Горизонтальный sharding (по строкам): самый популярный</h3><p>При горизонтальном шардинге мы «нарезаем» нашу базу данных по строкам. Допустим, у нас таблица с клиентами. Мы задаём диапазон ключу шардирования с user_id от 1 до 1 000 000. Данные в этом диапазоне, построчно будут храниться в шадре 1. Если user_id попадает в диапазон от 1 000 001 до 2 000 000, то эти данные отправляем на шадр 2. И так далее.</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-04-30/ced7c0e7-fcbb-4f28-870b-91682a38f689.png" alt="Что такое Sharding" /><figcaption>Горизонтальный шардинг</figcaption></figure><p>Благодаря этому способу мы можем равномерно распределять данные, и нам будет проще масштабировать систему при помощи создания новых шадров и добавления серверов.</p><p>Горизонтальный sharding — идеальный вариант, когда основная проблема — это огромное количество строк в таблицах и высокая нагрузка на чтение/запись.</p><h3>Вертикальный шардинг (по столбцам): разделение по функциональности</h3><p>Если горизонтальный шардинг режет таблицу поперёк (по строкам), то вертикальный — вдоль, разделяя столбцы. Таблица делится на несколько с меньшим количеством столбцов. Обычно они группируются по частоте использования или по смысловой нагрузке. Например, в таблице юзеров можно выделить часто запрашиваемые user_id, username, email в одну таблицу, а редко используемые — biography, preferences, last_login_details — в другую.</p><p>Это полезно, когда у таблицы очень много столбцов или когда группы столбцов имеют совершенно разные паттерны доступа. Мы можем улучшить производительность запросов, так как они работают с таблицами меньшей ширины.</p><h3>Directory-based sharding: использование хеш-таблицы маршрутов</h3><p>При горизонтальном и вертикальном шардинге маршрутизатор часто сам, при помощи специальных функций, определяет, какие данные в какой шадр отправить. Это не всегда удобно. При таком подходе мало гибкости. Поэтому был придуман вид шардинга, который опирается на хеш-таблицы и называется directory-based. Его суть в том, что мы создаём централизованный каталог, который связывает наши ключи шардирования и шарды.</p><p>Вот пример того, как это работает:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-04-30/8dc151d5-591c-4a6c-8564-898afc26aaa1.png" alt="Как работает шардинг в базах данных" /><figcaption>Directory-based sharding</figcaption></figure><ul><li>Клиентское приложение отправляет запрос (например, получить данные для order_id = 98765).</li><li>Маршрутизатор запросов перехватывает его.</li><li>Маршрутизатор обращается к каталогу: с запросом, где найти order_id = 98765.</li><li>Каталог ищет в своей таблице соответствий правило, под которое подпадает order_id = 98765. Для быстрого поиска он часто использует эффективные структуры данных, такие как хеш-таблицы или B-деревья (это внутренняя деталь реализации самого каталога).</li><li>Допустим, каталог находит правило «Диапазон order_id 90000-99999 → Shard-3» и сообщает это маршрутизатору.</li><li>Маршрутизатор перенаправляет исходный запрос на Shard-3.</li></ul><p>При таком подходе удобнее перемещать данные между шардами, изолировать их и менять логику.</p><h3>Range-based sharding: разбиение по диапазонам значений</h3><p>По сути, это тот же горизонтальный sharding с разбиением данных на кусочки по строкам при помощи диапазонов.</p><p>Администратор системы (или автоматизированный инструмент) определяет границы диапазонов для ключа шардинга. Маршрутизатор получает запрос, смотрит на значение этого ключа и сравнивает его с известными диапазонами, чтобы определить целевой шард.</p><p>Этот способ простой, логичный и отлично подходит для работы с данными за определённый период. Но у него есть проблема. Допустим, мы запустили форум и проводим шардирование по трём ключам:</p><ul><li>id от 1 до 1000 — шард 1;</li><li>id от 1001 до 2000— шард 2;</li><li>id от 2001 до 3000 — шард 3.</li></ul><p>Когда пользователи начнут регистрироваться, у нас будет активен шард 1, потом шард 2. Далее вся нагрузка перейдёт на шард 3. Они не будут одновременно равномерно работать. Это может стать проблемой при оптимизации.</p><h3>Hash-based sharding: равномерное распределение по хешу ключа</h3><p>Этот подход помогает добиться максимально равномерного распределения нагрузки по всем шардам. Работает следующим образом:</p><p><b>Берём значение ключа</b> для конкретной строки данных (например, user_id = 2001).</p><p><b>Применяем к нему хеш-функцию</b>. Хеш-функция (например, MD5, SHA-1, MurmurHash) — это алгоритм, который превращает входные данные (наш user_id) в строку или число фиксированной длины (хэш), которое выглядит почти случайно. Даже небольшое изменение на входе (например, user_id = 2001 и user_id = 2002) обычно даёт совершенно разные хеши.</p><p><b>Вычисляем номер шарда</b>. Чаще всего делим значение хеша на количество шардов и берём остаток от деления. Например, 548291 % 3 = 2. Далее в зависимости от остатка распределяем данные по шардам. Значение с остатком 2 пойдёт в шард 2, если остаток 1, то в шард 1 и так далее.</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-04-30/bb6c10d3-0c7a-4499-ab9a-11d2d3c34be0.jpg" alt="Что такое Sharding" /><figcaption>Hash-based sharding</figcaption></figure><p>Так мы получаем более равномерное распределение данных. Но из минусов — в такой базе сложно обрабатывать диапазоны и добавлять новые шарды в систему.</p><h2>Примеры реализации</h2><h3>MongoDB: встроенная поддержка шардинга</h3><p>MongoDB — это NoSQL база данных, которая была разработана с закосом на горизонтальное масштабирование. То есть она адаптирована к тому, чтобы работать на нескольких серверах и расширять это число по мере необходимости. Поэтому sharding здесь доступен из коробки, нам не надо заморачиваться со внешними расширениями.</p><p>Рассмотрим пример, как настроить sharding и работать с ним:</p><ul><li>sh.addShard() — добавляем сервер в кластер как шард. MongoDB понимает, что может использовать этот сервер для хранения части данных.</li><li>use socialApp; sh.enableSharding("socialApp") — переключаемся на базу данных «socialApp». При помощи команды sh.enableSharding() разрешаем шардинг в этой БД.</li><li>sh.shardCollection("socialApp.users", { "user_id": 1 }) — применяем sharding к коллекции users. Мы указываем полное имя коллекции (socialApp.users) и ключ шарда ({ "user_id": 1 }). Цифра 1 означает, что мы используем шардинг по диапазонам. Эти диапазоны не нужно задавать вручную, MongoDB определяет их самостоятельно.</li><li>db.users.insertMany([...]) — вставляем данные в коллекцию users. MongoDB автоматически определяет, на какой шард поместить каждого пользователя.</li><li>db.users.findOne({ user_id: 1 }) — запрашиваем данные пользователя user_id = 1. Mongos сам определит, на каком шарде они находятся.</li></ul><h3>PostgreSQL + Citus</h3><p>В PostgreSQL нет поддержки встроенного шардинга, поэтому приходится устанавливать на сервер Citus. Это популярное расширение, которое как раз добавляет возможности горизонтального масштабирования и шардинга. Оно превращает кластер стандартных серверов PostgreSQL в распределённую базу данных.</p><p>Посмотрим на пример использования SQL-команд для настройки шардинга с помощью Citus:</p><ul><li>CREATE EXTENSION citus; — активируем Citus в текущей базе данных.</li><li>CREATE TABLE app_logs (...) — создаём таблицу app_logs на узле-координаторе точно так же, как создали бы обычную таблицу в PostgreSQL.</li><li>SELECT create_distributed_table('app_logs', 'service_name'); — при помощи этой команды включаем sharding. Citus понимает, что таблицу app_logs нужно распределить по рабочим узлам, используя поле service_name как ключ шардинга. Citus по умолчанию применяет Hash-based sharding, то есть, равномерно распределяет по шардам при помощи хеш-функций.</li><li>INSERT INTO app_logs — добавляем данные логов. Citus перехватывает запрос, вычисляет хеш от значения service_name для каждой строки и распределяет данные по шардам.</li><li>SELECT ... FROM app_logs — запрашиваем данные. Если фильтруем по service_name (как в первом SELECT), Citus направит запрос на нужный шард.</li></ul><h3>MySQL + Vitess</h3><p>MySQL — ещё одна система управления базами данных, у которой по умолчанию нет поддержки шардинга. Ситуацию спасает Vitess. Это система кластеризации баз данных — что-то вроде сторонней платформы, которая помогает организовать работу в рамках кластера.</p><p>Vitess вместо прямых команд для шардинга определяет его правила в отдельном JSON-файле, который называется VSchema (Vitess Schema).</p><p>Допустим, у нас есть база данных commerce. Вот как она выглядит в виде кода:</p><p>А вот так она выглядит в виде таблицы:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-04-30/1dd751fd-aa6e-49f1-9883-6431fa53b08f.png" alt="Как работает шардинг в базах данных" /><figcaption>Пример структуры базы данных</figcaption></figure><p>В базе данных есть таблица orders, её мы и хотим шардировать по customer_id при помощи хеширования (hash-based sharding).</p><p>Файл VSchema (vschema.json) может выглядеть примерно так:</p><ul><li>"sharded": true — указываем, что база данных шардирована.</li><li>"vindexes" — определяем hash_index типа hash, который будет использовать хеш-функцию для распределения.</li><li>"tables" — описываются правила для конкретных таблиц.</li><li>"orders" — настраиваем таблицу orders.</li><li>"column_vindexes" — определяем, какой столбец является ключом ("column": "customer_id") и какой vindex ("name": "hash_customer_id") использовать для него.</li></ul><h2>Проблемы шардирования</h2><h3>Перераспределение шардов (resharding)</h3><p>Со временем может потребоваться изменить количество шардов или способ разделения данных. Например, добавить серверы для увеличения мощности или изменить ключ шардирования. Этот процесс называется решардингом.</p><p>При решардинге часто приходится перегонять большие объёмы данных между серверами. Если используется хеш-шардинг, и мы меняем количество шардов, то пересчитываются ключи, по которым распределяются данные.</p><p>Например, раньше у нас было 4 шарда. Мы брали user_id, например 9, делили на 4 и получали остаток — 1. Значит, данные шли на шард номер 1. После масштабирования стало 5 шардов, и 9 % 5 = 4 — теперь те же данные должны храниться на шардe 4.</p><p>Такое перемещение затратно по ресурсам: грузит сеть, диски, может занять часы или даже дни. Иногда для этого приходится останавливать запись, что делает процесс ещё рискованнее.</p><h3>Неравномерная нагрузка (hot shards)</h3><p>Вспомним вид шардирования Range-based sharding. Это когда мы разбиваем данные по диапазонам. У нас был пример выше с форумом и шардингом user_id:</p><ul><li>id от 1 до 1000 — шард 1;</li><li>id от 1001 до 2000— шард 2;</li><li>id от 2001 до 3000 — шард 3.</li></ul><p>Мы столкнулись с проблемой, что шард 1 и шард 2 после завершения диапазонов простаивали, а вся новая нагрузка приходилась на шард 3.</p><p>Такую проблему называют горячим шардом (hot shards). Производительность всей системы начинает зависеть от самого загруженного шарда. Преимущества шардирования снижаются.</p><p>Чтобы этого избежать, приходится либо более въедливо продумывать ключи шардирования, либо вручную разделять слишком нагруженный шард.</p><h3>Сложности с глобальными транзакциями и агрегациями</h3><p>Допустим, нужно перевести деньги со счёта А на счёт Б — операция состоит из двух шагов: списание и зачисление. Транзакция позволяет объединить их в единое целое: либо всё выполнится, либо ничего. Это защищает от потери данных и ошибок. В классических базах данных за это отвечают принципы ACID — они гарантируют надёжность в пределах одного сервера.</p><p>Но если счёт А находится на одном шарде, а счёт Б — на другом, стандартная транзакция не сработает. Между независимыми серверами нельзя просто так обеспечить ACID-гарантии. Для этого нужны сложные и медленные механизмы координации, например двухфазный коммит (2PC). Либо приходится идти на компромисс и использовать eventual consistency — когда данные приходят в согласованное состояние с небольшой задержкой. Например, деньги уже списались, но ещё не зачислились.</p><p>Аналогичная проблема и с агрегациями: посчитать сумму продаж или число пользователей уже не получится одной SQL-командой. Каждый шард сначала считает свою часть, а потом результат нужно собрать и объединить — это требует дополнительной координации и может усложниться при фильтрации или группировках.</p><h3>Сложность управления и мониторинга</h3><p>Шардированный кластер — это распределённая система, управлять которой сложнее, чем одним сервером.</p><p><b>Больше компонентов</b>: Вместо одной базы данных появляется множество шардов (часто с репликами), маршрутизаторы запросов, серверы конфигурации. Всё это нужно настраивать, обновлять и обслуживать.</p><p><b>Мониторинг</b>: Требуется отслеживать состояние каждого шарда, равномерность распределения нагрузки, задержки в сети, работу маршрутизаторов. Нужны более сложные инструменты мониторинга.</p><p><b>Отладка</b>: Найти источник проблемы в распределённой системе сложнее. Ошибка может быть где угодно: в приложении, маршрутизаторе, на одном из шардов или в сети.</p><p><b>Резервное копирование</b>: Создание согласованных резервных копий и восстановление данных со множеством независимых шардов требует более сложных процедур.</p><h2>Когда стоит применять Sharding</h2><h3>Рост объёма данных и нагрузок</h3><p>Sharding стоит применять, если БД сильно разрослась, хранить её на одном сервере становится сложно и дорого. Серверу приходится обрабатывать много данных, и поэтому увеличивается время отклика.</p><p>Иногда серверу приходится одновременно читать и записывать слишком много запросов. Система становится перегруженной, пользователи замечают задержки и нестабильную работу. Здесь тоже поможет sharding.</p><h3>Не справляется один сервер/реплика</h3><p>Допустим, у нас один сервер и он не справляется с запросами и большими данными. Конечно, мы можем заняться вертикальным масштабированием, поставить CPU производительнее, добавить больше ОЗУ и так далее. Однако у этого подхода есть ограничения. Во-первых, каким бы мощным ни был бы сервер, он со временем упрётся в потолок своей производительности. Во-вторых, иногда дешевле купить несколько новых серверов помощнее, чем прокачивать старый. Поэтому создание кластера и распределение в нём нагрузки при помощи шардинга — часто более выигрышное решение, чем один сервер.</p><h3>Потребность в геораспределённости или отказоустойчивости</h3><p>Если пользователи находятся в разных частях света, то деление данных и хранение ближе к ним может ускорить работу приложения. Мы можем при помощи шардинга размещать данные в разных дата-центрах, ближе к определённым группам пользователей. Например, так делает Youtube. Компания размещает свои сервера в разных странах, чтобы видео прогружались быстрее и в более высоком качестве.</p><p>Мы можем хранить все данные и обрабатывать запросы на одном сервере и сделать его реплику с копией данных. Если этот сервер падает, то его заменяет реплика. Но что, если эта реплика тоже упадёт? Тогда нам и помогает sharding с репликацией. В случае сбоев отвалятся только отдельные серверы с некоторыми наборами данных. Конечно, здесь тоже, в теории, можно положить весь кластер, включая реплики, но сделать это сложнее.</p><p>Шардирование — полезный инструмент при работе с СУБД. А узнать про большее число подобных инструментов можно в нашем <a href="https://t.me/+qUpIFTBINgJkOGJi">телеграм канале</a>!</p>]]></content:encoded>
    </item>
    <item>
      <title>Утилита с 30 000 звезд на GitHub: как пет-проект стал тулзой для LinkedIn и властей США</title>
      <link>https://tproger.ru/news/utilita-s-30-000-zvezd-na-github--kak-pet-proekt-stal-tulzoj-dlya-linkedin-i-vlastej-swa</link>
      <comments>https://tproger.ru/news/utilita-s-30-000-zvezd-na-github--kak-pet-proekt-stal-tulzoj-dlya-linkedin-i-vlastej-swa?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/utilita-s-30-000-zvezd-na-github--kak-pet-proekt-stal-tulzoj-dlya-linkedin-i-vlastej-swa</guid>
      <description><![CDATA[<p>Инструмент, начатый как пет-проект в 2004 году, стал инструментом для властей США и LinkedIn: 30 000 звезд, 50 сотрудников и путь от PHP до венчурной устойчивости</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/utilita-s-30-000-zvezd-na-github--kak-pet-proekt-stal-tulzoj-dlya-linkedin-i-vlastej-swa">Утилита с 30 000 звезд на GitHub: как пет-проект стал тулзой для LinkedIn и властей США</a>»</p>]]></description>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Стартапы]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[Пет-проект]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 01 May 2025 13:51:06 GMT</pubDate>
      <content:encoded><![CDATA[<p>Бен Хейнс <a href="https://medium.com/@ben_haynes/i-started-an-open-source-project-in-2004-8d38820a7ecd">начал</a> писать свой инструмент в 2004 году — задолго до GitHub, до стартапов и даже до появления у него детей.</p><p>Больше новостей — в нашем тг-канале «<a href="https://t.me/your_tech">Представляешь»</a></p><p>Он просто хотел заменить phpMyAdmin чем-то более безопасным и понятным для клиентов. Сегодня у его проекта — <a href="https://github.com/directus/directus">более 30 000 звезд</a>, клиенты из списка Fortune 500 и команда из 50 человек.</p><h2>10 лет в одиночку</h2><p>Первые 10 лет инструмент был сугубо личным. Без сообщества, без поддержки, без амбиций. Только PHP, MySQL и Бен. Когда-то он просто поставил на стол счетчик звезд с GitHub — и каждая новая звезда ощущалась как маленькая победа.</p><h2>10 000 звезд: первая волна</h2><p>Где-то в 2015 году о проекте начали говорить — в Reddit, Slack, GitHub Explore. К проекту присоединился Рейк ван Зантен, будущий со-основатель.</p><p>Вместе они вычистили кучу спагетти-кода, переписали все с PHP на Node и Backbone на Vue. Тогда же их позвали в Сан-Франциско — крупная компания хотела внедрить проект, но испугалась, что за ним стоит всего два человека без юрлица.</p><h2>20 000 звезд: время становиться бизнесом</h2><p>Хейнс закрыл имевшееся у него агентство и оформил компанию. Поднял $1 млн, собрал команду, запустил облачный сервис.</p><p>Затем, после сотни встреч с инвесторами и обвала венчурного рынка, нашел партнера, который понял ценность OSS. Удалось закрыть $8 млн — и с этого момента встал вопрос устойчивости: как зарабатывать, не предавая open-source?</p><p>Ответ — собственная лицензия с бесплатным использованием для всех, кроме корпораций. Работали даже с Брюсом Перенсом, сооснователем OSI.</p><h2>30 000 звезд: устойчивость</h2><p>Сегодня проект — это компания из 50 человек. Впервые на горизонте — прибыль. Продуктом пользуются правительственные агентства, крупнейшие компании, стартапы.</p><p>И да, недавно они тихо подняли еще $9 млн — на новый архитектурный рефакторинг.</p><p>Самое сложное, по словам Бена — сохранять баланс: открытость, прозрачность, вменяемую монетизацию и доверие сообщества.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как перевести проект на Laravel: пошаговый план перехода</title>
      <link>https://tproger.ru/articles/kak-perevesti-proekt-na-laravel--powagovyj-plan-perehoda</link>
      <comments>https://tproger.ru/articles/kak-perevesti-proekt-na-laravel--powagovyj-plan-perehoda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-perevesti-proekt-na-laravel--powagovyj-plan-perehoda</guid>
      <description><![CDATA[<p>Как перевести проект на Laravel. Показываем основные преимущества использования Ларавел. Рассматриваем пошаговую инструкцию нюансы переноса ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-perevesti-proekt-na-laravel--powagovyj-plan-perehoda">Как перевести проект на Laravel: пошаговый план перехода</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[Laravel]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[DPI]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 30 Mar 2025 09:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Когда код устаревает, его поддержка превращается в борьбу с хаосом. После пересмотра архитектуры приходит пугающее осознание: нужно переезжать на более современный стек. Однако непонятно, с чего начать.</p><p><i>В этой статье пошагово разберем перенос вашего проекта на Laravel. Вы узнаете, как мигрировать с минимальными рисками для разработки и пользователей.</i></p><h2>Шаг 1. Готовимся к миграции</h2><p>Посмотрите структуру проекта, чтобы выявить слабые места.</p><p>Архитектура далека от идеала, если проект вырос на хаотичных добавлениях новых функций.</p><p>Проанализируйте:</p><ul><li><b>Вид проекта</b>. Ваша разработка — это монолит, модульная система, API, микросервис?</li><li><b>Зависимости</b>. Определите, какие библиотеки использует проект. Совместимы ли они с Laravel?</li><li><b>Базу данных</b>. Если в БД встречаются дубли, отсутствуют ограничения, это нужно исправить заранее.</li></ul><p>В качестве теста на совместимость перепишите небольшую часть на Laravel. Возьмите один простой модуль и посмотрите, насколько это жизнеспособно.</p><h2>Стратегии перехода</h2><p>Выберем стратегию перехода:</p><ul><li>Big Bang,</li><li>Поэтапный перенос.</li></ul><p><b>Стратегия Big Bang</b> — это полная остановка текущего проекта и создание новой версии на Ларавел с нуля.</p><p>Подход идеален для устаревших и запутанных систем.</p><p>Из минусов — высокие риски. Во время разработки текущая версия может растерять пользователей. К тому же сроки реализации могут затянуться.</p><p><b>Стратегия с постепенным переходом</b> выглядит надежнее.</p><p>Система продолжает работать, а вы поэтапно меняете ее «под капотом».</p><p>Единственный нюанс — готовьтесь к сложностям поддержки, когда часть системы заработает в новой архитектуре, а часть останется в старой.</p><h4>Выбор подхода зависит от проекта</h4><p>Если систему легко поддерживать, то более безопасен постепенный переход.</p><p>Проект напоминает спагетти-код? Плохие новости — Big Bang неизбежен.</p><h2>Шаг 2. Разворачиваем новое окружение на Laravel</h2><p>Чтобы установить фреймворк, выполните команду:</p><p>Прежде чем работать с кодом, настроим окружение.</p><p>В корне проекта для этого есть файл конфигурации .env:</p><ul><li><b>APP_NAME</b>: имя приложения, чтобы оно отображалось в логах и заголовках.</li><li><b>APP_URL</b>: адрес, на котором приложение будет доступно (например, http://localhost).</li></ul><p>В будущем запланирована интеграция с существующей базой, поэтому лучше сразу настроить подключение.</p><h3>Подключение БД</h3><p>Laravel использует <b>Eloquent ORM</b> для взаимодействия с базой.</p><p>Настройка БД выполняется в том же разделе .env:</p><p>Для тестирования подключения запустите команду:</p><h2>Настройка маршрутов</h2><p>Маршруты изначально хранятся в файлах <i>routes/web.php</i> (для страниц) или <i>routes/api.php</i> (для <a href="https://tproger.ru/translations/luchshie-praktiki-razrabotki-rest-api-20-sovetov">REST API</a>).</p><p>В качестве примера добавим базовый маршрут приветствия:</p><p>Если у вас проект с десятками пользовательских маршрутов, интегрируйте их постепенно.</p><h2>Шаг 3. Переносим модели данных и бизнес-логики</h2><p>Eloquent ORM работает с классами, представляющими таблицы в базе данных.</p><p>Чтобы перенести существующую таблицу, нужно создать <b>модель</b>:</p><p>Этот класс автоматически подключается к таблице с именем products.</p><p>Когда название таблицы не соответствует модели, это можно указать явно:</p><p>Если в таблице есть нестандартные поля (например, столбцы с именами вроде created_time вместо created_at), их тоже можно легко обработать:</p><h2>Переносим схему БД</h2><p>Laravel использует механизм <b>миграций </b>для управления таблицами в базе и <b>сиды </b>для внесения данных.</p><p>Перенос структуры БД выполняется командой:</p><p>Миграция создается в папке <i>database/migrations</i>.</p><h3>Переносим данные</h3><p>Если текущая БД уже содержит данные, их можно перенести через <b>сиды</b>: файлы, которые заполняют таблицы данными.</p><p>Создаем сид:</p><p>Внутри метода run описываем данные:</p><h3>Переводим бизнес-логику в сервисы и фасады</h3><p>Старый проект состоит из функционала, размазанного по контроллерам? Улучшим структуру и сделаем код независимым. С этим помогут сервисы и фасады.</p><p><b>Сервисы </b>— это классы, которые объединяют бизнес-логику в одном месте.</p><p>Например, если проект выполняет расчеты цен и скидок, можно создать класс:</p><p>В этом классе описана бизнес-логика:</p><p>Теперь сервис можно вызывать в контроллерах и моделях.</p><p><b>Фасады </b>— это статический интерфейс к сервисам, который делает вызовы более читаемыми.</p><p>Например:</p><p>С фасадом вызов становится простым:</p><h2>Шаг 4. Перенос маршрутов и контроллеров</h2><p>Начнем с <b>маршрутов</b>. Они определяют, как пользователи будут взаимодействовать с приложением.</p><p>Если в старом проекте использовались API-запросы для работы с внешними сервисами или мобильными приложениями, перенесем их в <i>api.php</i> и добавим префикс api для маршрутов:</p><p>Теперь про <b>контроллеры</b>. Они отвечают за логику обработки запросов и взаимодействие с моделями. В Laravel контроллеры работают по правилам <b>MVC </b>(Model-View-Controller).</p><p>Пример обычного метода контроллера:</p><p>Laravel определяет маршруты групповыми методами — по префиксам, middleware или зонам авторизации.</p><p><b>Middleware </b>— это посредники, которые обрабатывают запросы до их поступления в приложение.</p><p>Навесим middleware на маршруты, требующие авторизации пользователя:</p><p><b>Политики </b>контролируют доступ к определенным ресурсам, например, правку или удаление записей.</p><p>Пример метода политики:</p><p>Политики можно подключать к маршрутам или напрямую вызывать в контроллерах.</p><h2>Шаг 5. Перенос фронтенда и представлений</h2><p>Если ваш старый проект использует обычные HTML-файлы, они легко преобразуются в Blade.</p><p><b>Blade </b>— это встроенный механизм шаблонов. С его помощью создают пользовательские интерфейсы.</p><p>Например, перенесем главную страницу сайта:</p><p>Blade-версия:</p><p>Теперь можно динамически передавать данные из контроллера:</p><p>Blade поддерживает механизм наследования, который упрощает работу с повторяющимися частями интерфейса.</p><h3>Интегрируем Vue.js или React</h3><p>Vue.js/React подключают, когда нужен динамичный и интерактивный интерфейс. Например, для <a href="https://tproger.ru/articles/ssr-ili-spa-veb-sajty-chto-vybrat-dlya-vas-i-vawego-biznesa">SPA</a>, реалтайм-функционала, сложных форм или фильтров.</p><p>Blade и JavaScript можно комбинировать: используйте Blade для рендеринга начального интерфейса и Vue.js/React для обработки интерактива.</p><h3>Динамический интерфейс без JS</h3><p><b>Livewire </b>— это инструмент для создания интерфейсов без необходимости обращаться к внешним библиотекам JavaScript. Преимущество в том, что весь код пишется на PHP.</p><p>Livewire пригодится для динамических форм, фильтрации таблиц, уведомлений. Он упрощает код, сохраняя гибкость.</p><h2>Шаг 6. Оптимизируем и тестируем проект</h2><p>Отправная точка улучшения производительности — работа с Blade-шаблонами. Laravel сам их оптимизирует, но есть практики по дополнительному ускорению:</p><ul><li><b>Минимизация логики в представлении</b>. Злоупотребление PHP внутри Blade замедляет рендеринг страниц. Вместо описания сложной логики в шаблонах ее лучше перенести в контроллер.</li><li><b>Кэширование шаблонов</b>. Работу приложения можно ускорить за счет запуска кэширования всех шаблонов, сокращая время компиляции — «<i>php artisan view:cache</i>».</li><li><b>Переиспользование</b>. Если фронтенд состоит из повторяющихся фрагментов, рекомендуется использовать Blade-компоненты.</li></ul><p>В приложениях SPA оптимизируем фрагменты JavaScript.</p><p><b>Laravel Mix</b> генерирует минифицированные CSS и JS. Проверьте размер этих файлов в папке <i>public/js</i>. Если их вес больше 1 МБ:</p><ul><li>Удалите лишние пакеты.</li><li>Используйте динамическую загрузку маршрутов или компонентов.</li></ul><p>Для Vue можно использовать динамическую загрузку, чтобы не грузить весь фронтенд сразу:</p><h3>Тестирование</h3><p>Убедимся, что приложение работает корректно.</p><p>Проверим, например, что страница приветствия открывается и показывает нужный текст:</p><p>Если используете Vue.js или React, для проверки компонентов применяйте <b>Jest </b>или <b>Mocha</b>.</p><p>Тест, который проверяет, что компонент отобразил нужный текст:</p><p>Если приложение работает с API:</p><p>Для проверки приложения под нагрузкой можно использовать <b>Artillery </b>или <b>JMeter</b>.</p><h2>Шаг 7. Разворачиваем и запускаем проект</h2><p>Перенесли данные, создали маршруты и контроллеры, внедрили представления, оптимизировали приложение и протестировали его. Остался последний шаг — развернуть проект на сервере и запустить его.</p><p>Выбор сервера зависит от предпочтений и нагрузок:</p><ul><li>Если важна скорость и масштабируемость, выбирайте <a href="https://tproger.ru/articles/video-osnovy-nginx-dlja-nachinajushhih-za-200-sekund">Nginx</a>. Он быстрее работает под высокой нагрузкой.</li><li>Если важен простой подход, используйте <a href="https://tproger.ru/video/video-osnovy-apache-kafka">Apache</a>. Он интегрируется с большинством систем.</li></ul><p>Фоновые задачи можно связать с <b>Supervisor</b>. Инструмент автоматически запускает воркеров при сбоях, обеспечивая бесперебойную обработку задач.</p><h3>Автоматизация развертывания</h3><p>Чтобы релиз прошел безболезненно, нужен рабочий процесс CI/CD. Например, в <a href="https://tproger.ru/articles/integraciya-ci-cd-processov-s-ispolzovaniem-github-actions">GitHub Actions</a> можно настроить сценарий, который:</p><ol><li>Проверит качество кода.</li><li>Установит зависимости.</li><li>Выполнит миграции.</li><li>Зальет проект на сервер.</li></ol><p>Предусмотрите откат, например, через <b>Spatie Laravel Backup</b>. Если что-то пойдет не так, у вас должна быть возможность вернуть предыдущую версию.</p><p>Инструмент <b>Sentry </b>поможет отслеживать ошибки, а <b>New Relic</b> — оценивать производительность.</p><h2>Заключение</h2><p>Устаревшие проекты уникальны, к каждому нужно искать индивидуальный подход. Надеемся, что пошаговое руководство станет основой для миграции вашего legacy-приложения на Laravel без переписывания кода с нуля.</p>]]></content:encoded>
    </item>
    <item>
      <title>Зачем разработчику знать SQL, если есть NoSQL? Разбираемся на примерах</title>
      <link>https://tproger.ru/articles/zachem-razrabotchiku-znat-sql--esli-est-nosql--razbiraemsya-na-primerah</link>
      <comments>https://tproger.ru/articles/zachem-razrabotchiku-znat-sql--esli-est-nosql--razbiraemsya-na-primerah?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Владислав Устинов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/zachem-razrabotchiku-znat-sql--esli-est-nosql--razbiraemsya-na-primerah</guid>
      <description><![CDATA[<p> Зачем разработчику знать SQL, если есть NoSQL. Показываем основные отличия SQL и NoSQL. Рассматриваем пошаговую инструкцию и важные особенности ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/zachem-razrabotchiku-znat-sql--esli-est-nosql--razbiraemsya-na-primerah">Зачем разработчику знать SQL, если есть NoSQL? Разбираемся на примерах</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[NoSQL]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 19 Mar 2025 10:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<h2>Ключевые отличия SQL и NoSQL</h2><h3>Структура данных: реляционные таблицы vs. Документо-ориентированные, графовые, ключ-значение базы</h3><p>SQL — язык запросов, с помощью которого мы можем обращаться к реляционным базам данных и манипулировать ими. Они имеют строгую структуру и отношения, логика их схемы напоминает таблицу или несколько связанных таблиц.</p><p>Рассмотрим пример таблицы ниже:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-03-12/a2ede9fc-5a44-48c8-8cb4-d49eae7761b6.jpg" alt="Зачем разработчику знать SQL" /><figcaption>Пример таблицы Excel</figcaption></figure><p>Это таблица excel, в которую занесены данные о различных персонажах. В ней мы можем фильтровать данные, искать их, сортировать содержимое, писать значения с разными типами, обращаться к данным во внешних таблицах. При помощи запросов SQL возможно всё то же самое в реляционной базе.</p><p>Давайте создадим нашу таблицу при помощи SQL:</p><p>Командой CREATE TABLE создаём таблицу, которую называем «Персонажи». В скобках прописываем название столбцов, напротив указываем тип данных, который здесь будет храниться. Например, VARCHAR(50) — это текст до 50 символов, DATE — дата, INT — число. PRIMARY KEY — первичный ключ строки. Он нужен, чтобы у каждой строки таблицы был свой уникальный номер.</p><p>Далее заполним нашу таблицу при помощи команды INSERT INTO Персонажи VALUES:</p><p>Заполняем значениями в кавычках, через запятую. Запятые отделяют столбцы друг от друга.</p><p>А теперь добавим ещё одного персонажа и отфильтруем значения по столбцу «Фильм_Сериал»:</p><p>Команда INSERT INTO добавляет нового персонажа в уже существующую базу.</p><p>В скобках после INSERT INTO мы перечисляем столбцы, которые хотим заполнить. VALUES — значения для этих столбцов.</p><p>Эта команда выбирает все столбцы в таблице «Персонажи», проверяя, что новое значение добавилось.</p><p>Далее проводим фильтрацию по сериалу: «Игра престолов»:</p><ul><li>SELECT — выбирает данные из столбцов.</li><li>После SELECTпишем, какие именно столбцы хотим видеть (не всё, а только эти шесть).</li><li>FROM Персонажи — указываем таблицу, из которой берём данные.</li><li>WHERE Фильм_Сериал — выбираем столбец, по которому будем искать данные.</li></ul><p>В результате получим вот такие данные:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-03-12/5ed2fec8-f939-4ba5-8297-ef5226c7c0c6.jpg" alt="Зачем разработчику знать SQL" /><figcaption>Визуализация вывода</figcaption></figure><p>NoSQL в сравнении с SQL не просто другой язык, а целая философия организации базы данных. Никаких строгих таблиц — всё зависит от того, с чем работаем. В NoSQL есть много видов данных, под каждый из них существуют свои системы управления базами данных (СУБД). Вот основные из них:</p><p><b>Документо-ориентированные базы (MongoDB):</b> данные лежат в виде документов, похожих на JSON, но это не совсем он, а BSON. Различия кроются в том, что это его бинарная версия.</p><p>Пример:</p><p>Слева в кавычках мы пишем название наших полей, например, «Персонаж». Далее через двоеточие указываем значение (тоже в кавычках) и заканчиваем запись для поля запятой. Всё это внутри фигурных скобок.</p><p><b>Ключ-значение (Redis):</b> это тип NoSQL баз данных, где информация хранится в виде пар «ключ-значение», как в словаре: ключ — уникальный идентификатор, значение — любые данные, связанные с ним. Например, запись Джона Сноу будет выглядеть так:</p><p>Внутри фигурных скобок прописываем ключ в кавычках. Далее через двоеточие пишем значение. Отделяем поля между собой при помощи запятой.</p><p><b>Графовые базы (Neo4j):</b> здесь данные — это узлы.</p><p>CREATE (Джон:Персонаж {имя: "Джон Сноу", дом: "Старк"});</p><p>Создаётся узел с меткой Персонаж, который представляет Джона Сноу. Узел имеет два свойства: имя со значением «Джон Сноу» и дом со значением «Старк». Переменная Джон — временное имя для ссылки на узел.</p><p>CREATE (Тирион:Персонаж {имя: "Тирион Ланнистер", дом: "Ланнистер"});</p><p>Далее создаётся ещё один узел с меткой Персонаж, представляющий Тириона Ланнистера. У него тоже два свойства: имя — «Тирион Ланнистер» и дом — «Ланнистер». Переменная Тирион позволяет ссылаться на этот узел.</p><p>CREATE (Джон)-[:ЛАЙК]-&gt;(Тирион);</p><p>Затем появляется направленная связь (ребро) между узлами Джон и Тирион. Она имеет тип ЛАЙК и указывает, что Джон «лайкает» Тириона. Скобки () обозначают узлы, а [:ЛАЙК] со стрелкой -&gt; показывает направление отношения.</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-03-12/f97cfff4-8608-4b0f-ba06-7ce5198da147.jpg" alt="Зачем разработчику знать SQL" /><figcaption>Пример визуализации графа из кода</figcaption></figure><h3>Гибкость схемы SQL против NoSQL: строгая схема vs динамическая структура</h3><p>Представьте, что у нас есть база данных с персонажами из фильмов и сериалов — огромная таблица на миллион строк. Теперь мы решили добавить в неё нестандартную запись: включить в список реальную историческую личность, а заодно создать новый столбец «факты», чтобы указать, чем личность запомнилась. Сделать это можно при помощи команды CREATE, но есть проблема.</p><p>Дело в том, что если мы создадим новый столбец в большой базе данных и запишем туда значение только для одного персонажа, то остальные строки в столбце для других примут значение null. И это не очень удобно, так как большое количество null усложняет запросы и может запутать разработчика при обработке данных.</p><p>В этом фундаментальное различие SQL и NoSQL. Первый плохо подходит для работы с неструктурированными данными.</p><p>В NoSQL мы можем при помощи MongoDB прописать значение только для одного персонажа, не трогая других:</p><p>Сравните данные Илона Маска и Сайтамы, у них есть различия в схеме.</p><p>Для такой записи в SQL нам пришлось бы добавлять поле «Чем известен» для всех персонажей в базе. Другие бы тогда получили значение null:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-03-12/e9f5f43b-ae55-41bf-a58c-bf1807d5c9bc.jpg" alt="Зачем разработчику знать SQL" /></figure><p>Из-за строгой схемы надо заранее продумывать логику структуры. Если база данных уже большая и её логику надо поменять, это чревато неудобствами.</p><p>У NoSQL, в отличие от SQL, нет строгой схемы, благодаря этому он отлично подходит для работы с плохо структурированными данными.</p><h2>Транзакции в SQL и NoSQL: ACID (SQL) vs. BASE (NoSQL)</h2><p>Транзакция — набор тех операций, которые либо выполняются полностью, либо не выполняются совсем. Представим перевод денег: снимаем 500 рублей с нашего счёта и отправляем их на другой. Если что-то сломается на полпути, транзакция либо отменится, либо завершит оба шага. В базах данных транзакции нужны, чтобы данные оставались надёжными. Рассмотрим основные различия транзакций SQL и NoSQL.</p><h3>ACID (SQL)</h3><p>SQL-базы данных работают по принципу ACID-транзакций, что гарантирует стабильность и предсказуемость работы с данными. Этот набор правил включает атомарность, согласованность, изоляцию и долговечность.</p><p><b>Атомарность (Atomicity)</b> — транзакция выполняется как единое целое. Если хоть одна операция внутри неё не удалась, всё отменяется. Например, если при переводе денег сервер внезапно отключился, система откатит изменения, и средства не исчезнут.</p><p><b>Согласованность (Consistency) </b>— данные всегда соответствуют правилам базы. Если на счёте 80$, а мы пытаемся перевести 100$, система просто не даст выполнить такую операцию.</p><p><b>Изоляция (Isolation) </b>— параллельные транзакции не мешают друг другу. Пока одна выполняется, другая видит только конечный результат. Например, если один процесс переводит 100$ со счёта A на счёт B, а другой в этот момент проверяет баланс, он увидит либо старое состояние, либо уже обновлённое, но никогда промежуточное.</p><p><b>Долговечность (Durability) </b>— завершённая транзакция остаётся в базе навсегда, даже в случае сбоя. Если мы пополнили счёт на 100$, эта информация будет сохранена, независимо от того, что произойдёт с сервером после.</p><h3>BASE (NoSQL)</h3><p>BASE-модель, которую используют NoSQL-базы данных, строится на трех принципах: базовая доступность, мягкое состояние и конечная согласованность. В отличие от строгих ACID-правил, здесь делается упор на скорость и масштабируемость, даже если это временно снижает точность данных.</p><p><b>Базовая доступность (Basically Available)</b> — система всегда отвечает на запросы, даже если часть данных ещё не синхронизирована. Например, ставя лайк, мы сразу видим его, даже если информация ещё не дошла до сервера.</p><p><b>Мягкое состояние (Soft State)</b> — данные могут временно быть несогласованными. Ради высокой доступности система допускает, что информация изменяется без нашего участия. Например, когда у нового видео на YouTube лайков больше, чем просмотров — это результат того, что одни данные обновились быстрее других.</p><p><b>Конечная согласованность (Eventual Consistency) </b>— если систему оставить в покое, она сама «додумает» и согласует данные между всеми узлами. Допустим, у поста 50 лайков, но у разных пользователей отображаются разные числа: кто-то видит 49, кто-то 53. Через некоторое время система синхронизируется, и у всех будет одинаковое значение.</p><p>BASE-жизнь — это про скорость и гибкость. Главное, чтобы данные в итоге сошлись, а не были идеальными в каждый момент времени.</p><h2>Масштабируемость: вертикальное (SQL) vs горизонтальное (NoSQL) масштабирование</h2><h3>Вертикальное масштабирование (SQL)</h3><p>Реляционные базы данных изначально проектировались для работы на одном сервере (или кластере серверов) с использованием строгой структуры данных (таблицы, строки, столбцы) и поддержки ACID-транзакций.</p><p>Если наше «железо» не справляется с обработкой реляционной базы, то проще его прокачать, например, установить больше памяти, либо купить новый сервер помощнее и перенести на него данные. При таком масштабировании мы как бы гонимся вверх, стараемся получить больше памяти и производительное «железо».</p><p>Конечно, можем купить второй сервер или кластер серверов и распределить на них часть нагрузки, но это будет сложно из-за архитектуры реляционных баз.</p><h3>Горизонтальное масштабирование (NoSQL)</h3><p>При горизонтальном масштабировании мы докупаем дополнительные сервера и распределяем между ними нагрузку. NoSQL базы данных изначально проектировались для работы на множестве серверов. Здесь не нужна строгая схема хранения данных, и они лучше оптимизированы для работы с большим объёмом информации.</p><p>Благодаря этому мы можем распределять нагрузку NoSQL среди множества серверов. Это значит, что если нам не хватает производительности, то можно просто докупить новые устройства.</p><p>Вертикальное масштабирование здесь тоже возможно, но оно часто дороже, хуже подходит для больших баз данных и, в целом, менее удобно из-за архитектуры NoSQL.</p><blockquote>Первое и главное преимущество SQL — строгая структура данных и операций. У базы есть контракт, который ты обязан соблюдать при добавлении, изменении или запросе данных. Правило простое: «Либо всё, либо откат». Второе преимущество — мощный и популярный язык запросов. Сложные аналитические задачи ему по плечу. Уверен, реляционные БД будущего будут опираться на опыт SQL.<br /><br />Строгая структура — одновременно и ограничение. Добавление полей или связей может стать проблемой при реализации на клиенте. Второй момент — горизонтальное масштабирование. Реляционные базы данных очень сложно масштабировать горизонтально. Ты не можешь просто подключить ещё один кластер и продолжать спокойно существовать. Есть ещё определённые проблемы с производительностью, если между объектами существует много связей.<br /><br />Плюсы NoSQL в гибкости, лёгкости масштабирования, высокой производительности при больших нагрузках и разнообразии предметно-ориентированных решений. Например, Redis — для кеширования, Firebase — для реалтайм-обновлений и так далее. Структуру данных можно менять на лету, идеально для проектов с частыми изменениями структуры данных.<br /><br />Минусы в том, что у многих NoSQL свои системы команд и запросов — их приходится учить. Также есть сложности с консистентностью данных.</blockquote><h2>Где использовать SQL и NoSQL</h2><h3>Сценарии, где SQL незаменим</h3><p>SQL хорош там, где важны точность, структура и сложные взаимосвязи данных.</p><h4>Финансовые и банковские системы</h4><p>Здесь цена любой ошибки — чьи-то деньги, поэтому важна точность. Транзакции по стандарту ACID гарантируют, что деньги не потеряются при сбоях. Связь между счетами, клиентами и операциями проще строить через реляционные базы данных.</p><p>Примеры систем: PostgreSQL, Oracle Database, Microsoft SQL Server.</p><h4>Аналитика и сложные запросы</h4><p>В аналитике нужно регулярно вытаскивать данные из таблиц и строить зависимости. В SQL есть операторы JOIN, GROUP BY и оконные функции, которые решают задачи, наподобие расчёта среднего чека за квартал, в пару строк.</p><p>Примеры систем: MySQL, Snowflake, Google BigQuery.</p><h4>Работа с отчётами и BI-системами</h4><p>Данные для бизнеса — это таблицы, сводки, графики. SQL легко интегрируется с инструментами вроде Power BI или Tableau. Строгая схема помогает избежать путаницы в метриках.</p><p>Примеры систем: PostgreSQL, SQL Server, Redshift.</p><h4>Логирование и аудит данных</h4><p>В этой сфере важно понимать, кто, что и когда изменил. Реляционные базы фиксируют историю изменений с точными связями. Триггеры и индексы ускоряют поиск по логам.</p><p>Примеры систем: SQLite, PostgreSQL, MariaDB.</p><h4>Управление складом и инвентаризацией</h4><p>Данные о товарах, поставках и остатках связаны между собой. Реляционная модель идеально описывает такие структуры. Запросы вроде «что заканчивается на складе» пишутся быстро и понятно.</p><p>Примеры систем: MySQL, Oracle Database.</p><h3>Где NoSQL работает лучше?</h3><p>NoSQL — это про скорость, гибкость и масштабирование. Там, где SQL требует строгих рамок, NoSQL даёт свободу и справляется с хаосом больших данных. Вот сценарии, где он выигрывает:</p><h4>Высоконагруженные системы и real-time сервисы</h4><p>Допустим, у нас стриминговый сервис, здесь миллионы запросов в секунду, а задержки недопустимы. Горизонтальное масштабирование размазывает нагрузку по серверам. Данные отправляются быстро, без сложных JOIN’ов.</p><p>Примеры систем: Cassandra, MongoDB, DynamoDB.</p><h4>Гибкие структуры данных и работа с JSON</h4><p>В реальной жизни данные далеко не всегда приходят в виде строгой схемы. У кого-то может быть указан email, у кого-то его нет, но есть телефон. Поэтому для работы с такой информацией лучше подходят документо-ориентированные базы, которые хранят JSON или BSON без строгой структуры. Если мы добавим новое поле, такая база не сломается.</p><p>Примеры систем: MongoDB, CouchDB, Firebase.</p><h4>Графовые базы для рекомендаций и соцсетей</h4><p>Иногда связи между объектами важнее самих данных. Графовые базы строят сети вроде «друзья друзей» или «похожие товары» за доли секунды. SQL для этой задачи медленнее.</p><p>Примеры систем: Neo4j, ArangoDB, OrientDB.</p><h2>Почему SQL и NoSQL нужно знать вместе?</h2><p>SQL даёт точность и структуру, данные в NoSQL — это про скорость и гибкость. В реальных проектах их часто используют вместе, чтобы закрыть слабые места друг друга.</p><h3>Примеры гибридных архитектур: SQL и NoSQL в одном проекте</h3><h4>Работа с каталогами товаров, запросами и системой рекомендаций в интернет-магазинах</h4><p>Представим интернет-магазин: каталог товаров и заказы лежат в SQL — там важны связи и точность. А рекомендации «похожие товары» или история просмотров — в NoSQL, чтобы быстро отдавать данные и не мучиться со схемой.</p><p>Например, PostgreSQL хранит данные о клиентах и транзакциях, а MongoDB — отзывы и пользовательские профили. Всё в одном проекте, каждый инструмент на своём месте.</p><h4>Кеширование запросов с помощью Redis и SQL</h4><p>SQL силён в сложных запросах, но в больших базах может тормозить. А если у нас есть операция, которая предполагает повторный подсчёт? Это будет долго. Здесь выручает Redis, NoSQL-база типа «ключ-значение».</p><p>Представим аналитику продаж: SQL вычисляет «топ-10 товаров за месяц» Готовый список сохраняем в Redis. Теперь, когда нам нужен этот топ, данные тянутся из Redis за миллисекунды, нам не надо заново проводить вычисления в SQL.</p><h4>Использование NoSQL для логов, SQL — для отчётности</h4><p>Логи — это поток данных: миллионы записей, структура не всегда предсказуема. NoSQL вроде Cassandra или MongoDB «переваривает» их без проблем благодаря скорости записи и горизонтальному масштабированию. А потом из этого хаоса SQL, например, MySQL, вытягивает нужное для отчётов: «сколько ошибок за день» или «кто чаще ломает систему». NoSQL собирает сырые данные, SQL их структурирует.</p><h2>Стоит ли учить SQL? Мнение экспертов</h2><p>Мы решили спросить у экспертов, что бы они посоветовали молодым разработчикам изучать в первую очередь, SQL или NoSQL. Делимся мнениями:</p><blockquote>Мой совет — начинайте с SQL. Вот почему:<br /><br />1) База знаний. SQL учит вас основам работы с данными — как их хранить и извлекать. Это фундамент, который пригодится в любом проекте, даже если вы потом перейдёте на NoSQL.<br /><br />2) Широкое применение. SQL встречается повсюду — от стартапов до банков. Знание SQL сразу даёт вам больше шансов найти работу или понять, что происходит в существующем проекте.<br /><br />Но это не значит, что NoSQL можно просто игнорировать. После SQL я бы рекомендовал изучить хотя бы одну NoSQL базу — например, Redis или MongoDB. Современные проекты часто требуют гибкости и скорости, которые дают NoSQL системы. Зная обе технологии, вы сможете выбирать инструмент под задачу, а не подстраиваться под то, что знаете.</blockquote><blockquote>Первым делом нужно освоить SQL. Это фундаментальный навык, который необходим в любой сфере, связанной с данными. Знание реляционных баз помогает понять, как правильно структурировать данные, оптимизировать запросы и обеспечивать их целостность. Независимо от того, с какой технологией будет иметь дело разработчик в будущем, понимание SQL даст ему прочную основу.<br /><br />После освоения SQL я бы рекомендовал изучить и NoSQL. Важно понимать, какие задачи он решает, какие бывают типы нереляционных баз и в каких случаях их применение оправдано. Даже если специалист в своей работе чаще использует SQL, знание NoSQL поможет ему грамотно проектировать архитектуру и принимать взвешенные технологические решения.</blockquote><blockquote>Не существует как такового единого NoSQL как системы управления базы данных, зачастую это очень сильно различающийся набор решений, поэтому стоит начать с SQL, для разных СУБД он довольно мало отличается синтаксически. SQL — это фундамент. NoSQL даст более полное понимание того, как можно работать с базами данных. Можно отметить, что в SQL добавляются фичи NoSql и наоборот.</blockquote><p>SQL и NoSQL желательно знать вместе. Как видно исходя из комментариев экспертов и примеров, SQL — первый ключ к базам данных, NoSQL — второй, для более сложных сценариев.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как настроить интеграцию между Great Expectations и Impala для работы с большими данными</title>
      <link>https://tproger.ru/articles/kak-nastroit-integraciyu-mezhdu-great-expectations-i-impala-dlya-raboty-s-bolwimi-dannymi</link>
      <comments>https://tproger.ru/articles/kak-nastroit-integraciyu-mezhdu-great-expectations-i-impala-dlya-raboty-s-bolwimi-dannymi?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-nastroit-integraciyu-mezhdu-great-expectations-i-impala-dlya-raboty-s-bolwimi-dannymi</guid>
      <description><![CDATA[<p>Рассказываем, как мы заставили GX подружиться с Impala. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-nastroit-integraciyu-mezhdu-great-expectations-i-impala-dlya-raboty-s-bolwimi-dannymi">Как настроить интеграцию между Great Expectations и Impala для работы с большими данными</a>»</p>]]></description>
      <category><![CDATA[Big Data]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 04 Feb 2025 14:29:07 GMT</pubDate>
      <content:encoded><![CDATA[<p>Всем привет, меня зовут Ольга Вишницкая, и я работаю главным аналитиком данных в одном из департаментов Газпромбанка. Работа эта, помимо прочего, сводится к постоянному наблюдению за новыми инструментами, призванными хоть немного облегчить жизнь тому, кто имеет дело с массивами данных. Мы тестируем, пробуем, отбрасываем неудачное и внедряем полезное.</p><p>В какой-то момент наши коллеги, отвечающие за качество данных, обратили внимание на Great Expectations (GX). Библиотека многообещающая: умеет валидировать, профилировать и даже составлять документацию автоматически. Однако есть одно «но»: Impala, наш основной SQL-движок для Hadoop, официально не поддерживается.</p><p>Мы решили схитрить и пустить данные через pandas DataFrame — инструмент, с которым GX ладит отлично. Тестовые прогонки показали обнадеживающие результаты, но когда дело дошло до настоящих объемов, стало ясно: DataFrame справляется с 15 000 строк за раз, а дальше — дробление, тормоза, потеря части функционала. Итог: сутки на обработку вместо минут, которые нужны Impala.</p><p>Вывод напрашивался сам собой: надо заставить GX работать с Impala напрямую. Теоретически это возможно — Impala ведь оперирует теми же данными куда быстрее. Практически же — GX о подобной интеграции ничего не знает. Документация хранит молчание. Пришлось экспериментировать.</p><p>После нескольких попыток, ошибок и обходных маневров мы нашли решение. Им и хочу поделиться.</p><p>Примечание: в статье описана работа с GX версии 0.17.19. Вышли новые релизы, но общий подход и логика решений остались прежними.</p><h2>Настройка проекта: подключаем Impala и кастомные проверки</h2><h3>Подключение к базе данных</h3><p>Перед тем, как приступить к работе, необходимо настроить подключение к Impala и организовать структуру проекта. Начнем с самого основного — соединения с базой данных:</p><p>Для этого используем функцию create_engine из SQLAlchemy, которая позволяет установить связь с Impala. Более детальную информацию о возможных параметрах конфигурации можно найти в <a href="https://docs.sqlalchemy.org/en/20/core/engines.html">официальной документации</a>.</p><h3>Добавляем кастомные проверки</h3><p>Теперь пришло время интегрировать собственные проверки. К сожалению, GX не предоставляет прямого механизма подключения проверок из произвольных папок — в документации указаны лишь способы через plugins или GitHub. Однако решение оказалось довольно простым:</p><ol><li>Создаем папку для пользовательских проверок в директории с основным кодом GX;</li><li>Подключаем нужные проверки в коде, указав путь к ним:</li></ol><p>Так, мы обеспечиваем корректное подключение кастомных правил в систему, позволяя использовать их наряду со стандартными инструментами Great Expectations.</p><h2>Основные проблемы, с которыми мы столкнулись</h2><h3>Проблема №1: Регулярные выражения</h3><p>Первым камнем преткновения стала попытка использовать проверки на регулярные выражения — expect_column_values_to_match_regex. При запуске на Impala они попросту не срабатывали, так как некоторые выражения Regex не поддерживались для этого диалекта.</p><p>Ошибки выглядели так:</p><p>У нас было два пути:</p><ol><li>Сделать pull request с изменениями в библиотеку GX. Но это означало бы долгое ожидание и, вероятно, последующие сложности с обновлениями версии в банковской инфраструктуре.</li><li>Создать свою собственную проверку, игнорируя диалект и подгоняя регулярные выражения под Impala. Именно этот путь мы и выбрали.</li></ol><h2>Решение</h2><p>Сначала копируем исходный файл проверки регулярных выражений в свою директорию. Не забываем изменить его название, а также поменять наименование проверки во всех местах, где она указана. В нашем случае мы добавили суффикс _impala:</p><p>В файле expect_column_values_to_match_regex_impala подключаем файл с проверкой:</p><p>Главное — заменить все названия проверок на свои.</p><p>Далее копируем еще один <a href="https://github.com/great-expectations/great_expectations/blob/f7fc2919b2950165bd490ceeced20320fefc4e25/great_expectations/expectations/metrics/column_map_metrics/column_values_match_regex.py#L26">файл</a> в свою директорию, меняем его название. В самом файле модифицируем переменные condition_metric_name и regex_expression. Метод SQLAlchemy использует функцию get_dialect_regex_expression, которая вызывает ошибку диалекта, так как Impala не входит в <a href="https://github.com/great-expectations/great_expectations/blob/f7fc2919b2950165bd490ceeced20320fefc4e25/great_expectations/expectations/metrics/util.py#L82">поддерживаемые базы данных</a>. Поэтому мы отключаем вызов этой функции и формируем наше регулярное выражение (переменная regex_expression) под Impala, взяв за основу выражение из MySQL:</p><p>Теперь формируем условие регулярного выражения с помощью класса BinaryExpression из SQLAlchemy, где:</p><ul><li>column — проверяемая колонка</li><li>sqlalchemy.literal(regex) — регулярное выражение</li><li>sqlalchemy.custom_op("REGEXP") — оператор</li></ul><p>После выполнения этого выражения получается строка вида table_nm REGEXP '%abv', в которой:</p><ul><li>table_nm — колонка</li><li>REGEXP — оператор</li><li>'%abv' — регулярное выражение</li></ul><p>Важно! Не забудьте добавить подключение BinaryExpression. Используйте literal(regex). Именно literal — без него не отработает.</p><h3>Проблема №2: Зарезервированные слова</h3><p>В процессе работы GX на Impala мы столкнулись с синтаксическими ошибками. Как оказалось, причина заключалась в том, что GX, при формировании запросов к базе данных, использует зарезервированные в Impala слова. Эти слова не могут быть использованы в качестве идентификаторов в базе данных. Вот примеры ошибок:</p><h4>Решение</h4><p>Для устранения данной проблемы необходимо заменить метку (label)  на другое подходящее имя, которое не вызывает конфликтов с диалектом. Например, в первой ошибке ключевым словом было condition, и мы заменили его на другое, обновив все файлы, где использовалась эта проверка.</p><p>В случае с типом NUMERIC достаточно просто заменить его на INTEGER, который как раз и предложен в ошибке в качестве корректного варианта.</p><p>Вот пример изменений в коде:</p><p>Было:</p><p>Стало:</p><p>Чтобы понять, в каких именно файлах необходимо внести изменения, мы обратились к логам. Логи содержат информацию о пути возникновения ошибок. Так мы находили проблемные файлы на GitHub, а затем прослеживали цепочку подключений, чтобы выяснить, откуда пришла функция проверки.</p><h3>Проблема №3: Подзапросы в Impala</h3><p>Следующая трудность, с которой мы столкнулись, касалась использования подзапросов. При работе с некоторыми проверками GX (например, ExpectColumnValuesToBeUnique) мы сталкивались с ошибкой:</p><p>Дело в том, что GX использует вложенные подзапросы в разделе SELECT, которые запрещены в Impala.</p><h4>Решение</h4><p>Эту проблему можно обойти, если вынести не поддерживаемый Impala подзапрос в отдельный запрос и его результат подставить в основной подзапрос.</p><p>За основу мы взяли запрос из переменной unexpected_condition в файле map_condition_auxilliary_methods.py, вывели его через print и с помощью методов конструктора запросов SqlAlchemy сформировали такой же запрос в поддерживаемом Impala формате.</p><p>Вот как выглядит исходный запрос:</p><p>Из этого запроса нужно выделить подзапрос, который Impala не может обработать:</p><p>С помощью метода SqlAlchemy этот запрос будет выглядеть так:</p><p>После выполнения мы получаем результат (назовем его условно result_impala) и подставляем в окончательный запрос:</p><h2>Последовательность замены файлов</h2><p>В процессе работы над проблемами, связанными с зарезервированными словами и подзапросами, нам понадобилось заменить несколько файлов. Вот полная последовательность этих изменений:</p><ol><li>Заменяем наименование проверок (чтобы они отличались от стандартных вариантов в GX) в подключении и классах: <a href="https://github.com/great-expectations/great_expectations/blob/f7fc2919b2950165bd490ceeced20320fefc4e25/great_expectations/expectations/core/expect_column_values_to_be_unique.py">great_expectations/expectations/core/expect_column_values_to_be_unique.py</a></li><li>Меняем только подключение в следующем файле: <a href="https://github.com/great-expectations/great_expectations/blob/f7fc2919b2950165bd490ceeced20320fefc4e25/great_expectations/expectations/metrics/column_map_metrics/column_values_unique.py">great_expectations/expectations/metrics/column_map_metrics/column_values_unique.py</a></li><li>Выполняем изменения здесь: <a href="https://github.com/great-expectations/great_expectations/blob/f7fc2919b2950165bd490ceeced20320fefc4e25/great_expectations/expectations/metrics/map_metric_provider/column_map_metric_provider.py">great_expectations/expecttions/metrics/map_metric_provider/column_map_metric_provider.py</a></li><li>Также изменяем этот файл: <a href="https://github.com/great-expectations/great_expectations/blob/f7fc2919b2950165bd490ceeced20320fefc4e25/great_expectations/expectations/metrics/map_metric_provider/map_metric_provider.py">great_expectations/expectations/metrics/map_metric_provider/map_metric_provider.py</a></li><li>И, наконец, меняем файл, как описано в разделе «Проблема №1: Регулярные выражения»: <a href="https://github.com/great-expectations/great_expectations/blob/f7fc2919b2950165bd490ceeced20320fefc4e25/great_expectations/expectations/metrics/map_metric_provider/map_condition_auxilliary_methods.py">great_expectations/expectations/metrics/map_metric_provider/ map_condition_auxilliary_methods.py</a></li></ol><p>В результате наших поисков и экспериментов мы обрели решение, которое соединяет GX с Impala. Да, порой наш путь не был изысканным — подмена файлов библиотеки могла бы вызвать сомнения у стороннего наблюдателя. Но в тех случаях, когда нужно было получить работающий инструмент немедленно, этот способ оказался вполне оправданным. И если у вас есть мысли о том, как можно было бы обойтись без таких компромиссов, — смело делитесь ими в комментариях.</p>]]></content:encoded>
    </item>
    <item>
      <title>Это БАЗА (данных): Как подключиться и выполнить запрос?</title>
      <link>https://tproger.ru/articles/kak-podklyuchitsya-k-baze-dannyh-i-vypolnit-zapros-</link>
      <comments>https://tproger.ru/articles/kak-podklyuchitsya-k-baze-dannyh-i-vypolnit-zapros-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Елизавета Малышева]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-podklyuchitsya-k-baze-dannyh-i-vypolnit-zapros-</guid>
      <description><![CDATA[<p>Как подключиться к базе данных. Показываем основные запросы к базам данных. Рассматриваем пошаговую инструкцию по использованию ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-podklyuchitsya-k-baze-dannyh-i-vypolnit-zapros-">Это БАЗА (данных): Как подключиться и выполнить запрос?</a>»</p>]]></description>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[NoSQL]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Уязвимость]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 16 Jan 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Хотите заплатить хакерам $15 миллионов за свои данные?</p><p>Это не шутка. Именно<a href="https://www.interfax.ru/world/920813"> такую сумму</a> заплатила американская сеть казино Caesars Entertainment злоумышленникам, которые увели их БД.</p><p>База данных ––  самое ценное, что есть у каждой компании. Именно в ней хранится вся чувствительная и важная для бизнеса информация. В этой статье расскажем, какие есть базы данных и как правильно с ними работать: подключаться и делать запросы.</p><h2>Такие разные базы данных</h2><p>Базы данных — основной инструмент программирования. БД хранят важную информацию о пользователях и позволяют этой информацией управлять.</p><p>Они делятся на два основных типа: реляционные и нереляционные.</p><p><b>Реляционная база</b> — как большой шкаф с ящиками. У каждого своя подпись, и в нём лежат только определенные вещи по порядку. Например, один ящик для носков, второй для шапок, третий –– для носовых платков.</p><p>Все очень аккуратно, ничего не теряется, но если нужно что-то изменить, например, носки переложить в ящик с платками –– будет не так-то просто.</p><p>Чтобы делать запросы к реляционной базе, нужно использовать язык SQL. А обрабатывать эти запросы будет СУБД –– система управления базами данных. Простыми словами –– штука, которая помогает вам управлять самой базой. Что-то из шкафа вытащить, кого-то в него спрятать.</p><p><b>Нереляционная база данных</b> — как огромная коробка, куда можно складывать всё, что угодно и как угодно. Это удобно, но для системы с чёткой структурой не подойдёт.</p><p>Какой тип БД выбрать для проекта –– зависит от целей компании, размера и особенностей бизнеса. Разберём каждый тип.</p><h2>Реляционные базы данных (SQL)</h2><p>Реляционные базы –– таблицы, где данные организованы в строки и столбцы. У каждой таблицы строгая схема, которая определяет типы данных и их взаимосвязь. Реляционные базы используются для приложений, где важны точность и согласованность информации.</p><p>Посмотрим на конкретные примеры.</p><h3>MySQL</h3><p>Очень популярная база с открытым исходным кодом. Она надежная, удобная и быстрая. MySQL часто используют для веб-приложений. Например,  Airbnb, Netflix и Uber.</p><p>Её любят, потому что у неё качественная и подробная документация, а также большое сообщество.</p><h3>PostgreSQL</h3><p>Мощная и универсальная реляционная база данных, которая предлагает расширенные возможности. Среди них —  работа с JSON, хранение массивов и поддержка пользовательских типов данных. Это делает PostgreSQL гибким инструментом для решения самых разнообразных задач.</p><p>СУБД используется в сложных приложениях, где важны высокая надежность и гибкий функционал.</p><h3>SQLite</h3><p>Эта однофайловая СУБД мало весит и не требует сервера для работы. Она идеально подходит для небольших приложений, мобильных устройств и тестирования.</p><p>Если нужно будет что-то куда-то переносить –– процесс пойдёт быстро. За эту простоту SQLite и любят.</p><h2>Нереляционные базы</h2><p>Нереляционные базы данных подходят для работы с большими объемами, которые могут быть неструктурированными или слабо структурированными.</p><p>В отличие от реляционных, у этих баз нет строгой схемы, что делает их гибкими и удобными для многих современных приложений.</p><p>Разберём самые популярные варианты нереляционных баз.</p><h3>MongoDB</h3><p>NoSQL-база данных, которая хранит данные в формате JSON, обеспечивает гибкость и простоту работы. MongoDB часто используется в приложениях, требующих динамической структуры данных, а также в учебных и небольших проектах благодаря своей доступности и лёгкости освоения.</p><h3>Redis</h3><p>Высокопроизводительная база данных, оптимизированная для минимизации задержек при доступе к данным. Идеально подходит для кэширования, управления сессиями, обработки очередей сообщений и других задач, требующих мгновенного отклика.</p><h2>В чём разница между базами данных</h2><p>Выбор базы данных — долгосрочное решение, от которого зависит эффективность работы вашего приложения. Давайте подробнее разберём различия между реляционными и нереляционными базами данных, чтобы помочь вам сделать осознанный и правильный выбор.</p><p>Структура данных</p><figure><img src="https://media.tproger.ru/user-uploads/105990/2025-01-10/0da24965-ccd4-4f79-b395-82f484763ae0.png" alt="" /></figure><p>Масштабируемость</p><figure><img src="https://media.tproger.ru/user-uploads/105990/2025-01-10/30f9658d-daa5-46b7-932f-0e7772881a03.png" alt="" /></figure><p>Скорость и производительность</p><figure><img src="https://media.tproger.ru/user-uploads/105990/2025-01-10/05f69730-26ff-4f9c-ba20-044a59df6d02.png" alt="" /></figure><p>Выбор зависит от потребностей проекта: для сложных транзакционных систем с жесткой структурой данных лучше использовать реляционные базы, а для гибких, масштабируемых приложений с неструктурированными данными — нереляционные.</p><p>Для работы с базами данных важно уметь выполнять ключевые операции: извлечение, добавление, обновление и удаление данных. Разберём, что такое SQL-запросы и как выполнение этих операций отличается в реляционных и нереляционных базах данных.</p><h2>Подключаемся к MySQL</h2><p>Для реляционных баз данных используются стандартные операции:</p><ul><li>SELECT — получить данные;</li><li>INSERT — добавить новые данные;</li><li>UPDATE — обновить существующие данные;</li><li>DELETE — удалить данные.</li></ul><p>Поработаем с ними на примере MySQL. Представим, что у нас есть база с пользователями нашего блога. Чтобы поработать с ней, нужно настроить соединение с программой. Разберём этот процесс шаг за шагом.</p><h3>Шаг 1. Устанавливаем библиотеку</h3><p>Для работы с MySQL в Python нам понадобится библиотека mysql-connector-python.</p><p>Дла этого напишем команду в терминале:</p><p>С помощью неё можно подключиться к базе, отправлять к ней запросы и обрабатывать результаты этих запросов.</p><h3>Шаг 2. Настраиваем подключение</h3><p>Чтобы подключиться к базе данных MySQL, необходимо знать её параметры:</p><ul><li>Хост: адрес сервера, где находится база данных. Это может быть localhost;</li><li>Порт: номер порта для подключения. По умолчанию для MySQL — 3306-й порт;</li><li>Пользователь: имя пользователя, который имеет доступ к базе;</li><li>Пароль: пароль для этого пользователя;</li><li>Имя базы данных: конкретная база, с которой вы хотите работать.</li></ul><p>Как это может выглядеть:</p><ul><li>Хост: localhost</li><li>Порт: 3306</li><li>Пользователь: root</li><li>Пароль: “”</li><li>Имя базы данных: test_db</li></ul><h3>Шаг 3. Подключаемся к базе данных</h3><p>Теперь создадим программу, которая установит соединение с MySQL.</p><h4>Что тут происходит:</h4><ol><li>Импорт нужных библиотек: mysql.connector — это основной модуль для работы с MySQL в Python. Error — класс для обработки ошибок;</li><li>Настройка подключения: Используем метод mysql.connector.connect, в который передаются параметры: host, user, password и database. Это наши настройки для базы данных;</li><li>Проверка подключения:Метод is_connected() из переменной connection проверяет, удалось ли установить соединение;</li><li>Выполнение запросов:Создаём курсор для выполнения SQL-запросов с помощью connection.cursor(). После этого можно делать запросы к базе. Выбираем конкретную базу, получаем все данные, добавляем в неё сущность, а затем удаляем её. Последний запрос — получение одного конкретного юзера;</li><li>Закрытие соединения:Закрываем соединение с помощью метода connection.close() для того, чтобы избежать утечек ресурсов и проблем с безопасностью.</li></ol><p>Вы также можете обернуть код в try-except, чтобы отловить непредвиденные ошибки и не уронить сервер.</p><p>С помощью этого подхода можно быстро настроить подключение к MySQL и начать работу с базой данных в Python-проекте.</p><h2>Подключаемся к MongoDB</h2><p>Для нереляционных баз используем NoSQL-запросы. Функционал такой же: добавление, удаление, изменение и получение данных. А выглядят они по-другому. Посмотрим на примере MongoDB.</p><p>Для работы с MongoDB в Python используется библиотека pymongo. Разберём, как настроить соединение, выбрать базу данных и выполнить простой запрос.</p><h3>Шаг 1. Устанавливаем библиотеку</h3><p>Для начала установим библиотеку pymongo на своём компьютере. Введём команду в терминал:</p><h3>Шаг 2. Настраиваем подключение</h3><p>Чтобы подключиться к MongoDB, нужно знать параметры базы:</p><ul><li>Хост: адрес сервера;</li><li>Порт: порт, на котором работает MongoDB. По умолчанию — 27017;</li><li>Имя базы данных: название базы, которую вы хотите использовать;</li></ul><p>MongoDB автоматически создаст базу данных, если она не существует.</p><p>Пример настроенной базы:</p><ul><li>Хост: localhost</li><li>Порт: 27017</li><li>Имя базы данных: test_db</li></ul><h3>Шаг 3. Подключаемся и выполняем запрос</h3><p>Нам нужно подключиться к базе данных MongoDB, добавить, удалить и получить данные коллекции:</p><p>Разберём подробнее:</p><ol><li>Импорт библиотеки: Используем MongoClient из библиотеки pymongo, чтобы создать подключение к базе;</li><li>Создание подключения: Используем данные хоста и порта, где запущен MongoDB;</li><li>Выбор базы данных и коллекции: Выбираем нужную базу данных. В нашем случае –– test_db. Если базы нет, MongoDB создаст её при добавлении первого документа;</li><li>Добавление документа: Добавляем новый документ с пользователем с помощью insert_one(). А также выводим в консоль информацию о добавленном пользователе;</li><li>Удаление. Удаляем юзера и проверяем, получилось ли. Если нет, в консоли увидим запись, что такого юзера не существует;</li><li>Выполнение запроса: Ищем только что добавленный документ методом find_one() и проверяем, нашли ли. Тут то же самое: если юзера нет, то в консоли мы это увидим;</li><li>Закрытие подключения: Закрываем вызов через client.close() и оповещаем самих себя в консоли.</li></ol><p>Вы могли заметить, что мы везде заканчиваем код закрытием соединения. Это важно по нескольким причинам:</p><ol><li>Подключение к базе данных –– ресурсы сервера и клиента. Если соединение не закрыть, ресурсы останутся занятыми. Значит, их нельзя будет использовать для более нужных вещей;</li><li>Неиспользуемые открытые соединения приводят к утечкам памяти;</li><li>Открытое соединение может стать уязвимостью для атак, несанкционированного доступа или SQL-инъекций.</li></ol><p>В этом фрагменте кода реализовано то же самое, но с улучшениями. Мы обернули его в блок try-except, чтобы защитить сервер от ошибок и предотвратить его аварийное завершение работы.</p><p>В этой статье мы лишь поверхностно коснулись темы баз данных. Если у вас ещё нет лишних денег на выкуп своих данных, рекомендуем инвестировать время в изучение основ и тонкостей работы с БД.</p><p>Качественно спроектированная база данных не только повысит эффективность и прибыльность бизнеса, но и защитит его от серьёзных рисков. Кроме того, вы значительно прокачаете свои навыки программирования.</p><p>Удачи в разработке и безопасности ваших данных! 🚀</p>]]></content:encoded>
    </item>
    <item>
      <title>Фреймворки, меняющие игру: выбираем идеальный инструмент для ваших веб-проектов</title>
      <link>https://tproger.ru/articles/obzor-populyarnyh-frejmvorkov-dlya-veb-razrabotki</link>
      <comments>https://tproger.ru/articles/obzor-populyarnyh-frejmvorkov-dlya-veb-razrabotki?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/obzor-populyarnyh-frejmvorkov-dlya-veb-razrabotki</guid>
      <description><![CDATA[<p>Популярные фреймворки для веб-разработки. Показываем основные виды фреймворков. Рассматриваем пошаговую инструкцию по использованию ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/obzor-populyarnyh-frejmvorkov-dlya-veb-razrabotki">Фреймворки, меняющие игру: выбираем идеальный инструмент для ваших веб-проектов</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Ruby on Rails]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Angular]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 10 Jan 2025 09:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Выбор фреймворка влияет на скорость, удобство разработки, производительность, масштабируемость и поддержку приложения. Рассмотрим популярные варианты для веб-разработки фронтенда, бэкенда и фулстека и сравним их между собой.</p><h2>Frontend фреймворки</h2><h3>React</h3><p>Это самый популярный фреймворк для создания веб-приложений. React используется в лендингах, динамических веб-приложениях и даже мобильных приложениях (<a href="https://tproger.ru/articles/your-first-app-in-react-native">React Native</a>).</p><p>UI здесь разбивается на независимые и переиспользуемые блоки. Такие компоненты легко интегрировать, комбинировать в разных частях приложения или между проектами. Фреймворк ускоряет разработку и рефакторинг.</p><p>React обращается к DOM только для обновления изменившихся компонентов. За счет этого повышается производительность приложения.</p><p>Пример простого React компонента:</p><h4>Преимущества фреймворка:</h4><ul><li>Облегчает повторное использование кода и поддержку приложений;</li><li>Имеет множество дополнительных библиотек и инструментов;</li><li>Виртуальный DOM снижает прямые манипуляции с DOM и повышает производительность приложения;</li><li>Фреймворк пользуется популярностью в сообществе. Как результат  —  множество учебников, разборов документации и сторонних библиотек.</li></ul><h4>Недостатки фреймворка:</h4><ul><li>Концепции JSX и управления состоянием могут быть сложны для новичков;</li><li>Плохая кроссбраузерная поддержка;</li><li>Требует дополнительных библиотек для маршрутизации и управления состоянием.</li></ul><h3>Vue.js</h3><p>Vue используется для разработки простых лендингов и комплексных веб-приложений. Это гибкое решение, которое можно интегрировать в проекты постепенно.</p><p>Преимущество Vue в его простоте и низком пороге входа. При этом фреймворк сохраняет статус мощного инструмента для разработки сложных веб-приложений.</p><p>Vue автоматически отслеживает зависимости между блоками и обновляет DOM при их изменении, как React.</p><p>Компонентная архитектура Vue позволяет разбивать UI на переиспользуемые части. Разметка, стили и логика разделяются «оболочкой», а это облегчает поддержку и масштабирование приложения.</p><p>Пример простого компонента Vue:</p><p>Экосистема Vue включает множество библиотек и плагинов, расширяющих возможности фреймворка. Например, Vuex для управления состоянием, Vue Router, Nuxt.js и другие.</p><h4>Преимущества фреймворка:</h4><ul><li>Понятный синтаксис и подробная документация;</li><li>Может использоваться как библиотека или цельный фреймворк в зависимости от проекта;</li><li>Есть поддержка серверного рендера;</li><li>Автоматически обновляет интерфейс при изменении данных;</li><li>Имеет небольшой вес файлов.</li></ul><h4>Недостатки фреймворка:</h4><ul><li>Меньше ресурсов и сторонних библиотек по сравнению с React и Angular;</li><li>Неполная документация на русском языке.</li></ul><h3>Angular</h3><p>С помощью Angular разрабатывают клиентские части веб-приложений. Этот фреймворк сложнее Vue и React.</p><p>Angular чаще используют для крупных веб-приложений. Например, панели администрирования, системы управления контентом и т. д.</p><p>По аналогии с Vue и React, фреймворк разбивает приложение на независимые, переиспользуемые блоки кода. Компоненты: шаблон; класс, описывающий поведение; стили.</p><p>Освоение Angular требует больше времени и усилий по сравнению с Vue и React из-за архитектуры и специфических концепций. Нужны углубленные знания по внедрению зависимостей, декораторам и модулям.</p><p>Пример простого Angular-компонента:</p><h4>Преимущества фреймворка:</h4><ul><li>Богатый выбор инструментов, шаблонов, которые сокращают сроки реализации сложных приложений;</li><li>Angular CLI расширяется за счет shematics, поэтому его легко доработать под конкретные задачи;</li><li>Есть поддержка TypeScript: статическая типизация улучшает качество кода;</li><li>Встроенная утилита для обновления проекта при переходе на новую версию Angular.</li></ul><h4>Недостатки фреймворка:</h4><ul><li>Ангуляр сложнее, чем Вью и Реакт. Его изучение занимает больше времени, если это первый фреймворк в карьере разработчика.</li></ul><h2>Backend фреймворки</h2><h3>Django (Python)</h3><p>Django подходит для широкого спектра приложений — от блогов до высоконагруженных веб-сервисов. Админ-панель фреймворка упрощает управление контентом и пользователями. Django часто используют для разработки новостных сайтов, интернет-магазинов, социальных сетей и образовательных платформ.</p><p>Фреймворк содержит множество инструментов для решения общих задач веб-разработки. «В комплекте» готовые библиотеки для аутентификации пользователей, администрирования контента, работы с формами, маршрутизации URL.</p><p>Django следует архитектурному шаблону Model-View-Controller (MVC). Модели определяют структуру данных, представления обрабатывают логику и взаимодействие с моделями, а шаблоны отвечают за представление данных пользователю.</p><p>Сильная сторона Django — его ORM (Object-Relational Mapping). Интерфейс для работы с базой данных на Python используется для написания сырых SQL-запросов. Django поддерживает PostgreSQL, MySQL, SQLite, Oracle.</p><p>Если ищете универсальный фреймворк для бэкенд-разработки на Python, Django определенно заслуживает вашего внимания.</p><p>Пример модели Django:</p><p>В примере определяем модель Article с полями title, content и published_at. Метод __str__ возвращает строковое представление объекта:</p><p>Представление article_list получает объекты Article из базы данных и передает их в шаблон для отображения.</p><h4>Преимущества фреймворка:</h4><ul><li>Широкий набор инструментов: включает ORM, аутентификацию и админ-панель;</li><li>Фреймворк задаёт структуру проекта — помогает разработчикам понимать, как и где добавлять новую функцию;</li><li>Защищен от SQL-инъекции и подделки межсайтовых запросов;</li><li>Подходит для высоконагруженных приложений.</li></ul><h4>Недостатки фреймворка:</h4><ul><li>Django ORM уступает последней SQLAlchemy.</li></ul><h3>Ruby on Rails (Ruby)</h3><p>Rails подходит для быстрого прототипирования и проектов, ориентированных на работу с базами данных. Его используют для SaaS-платформ, CRM-систем, CMS, маркетплейсов и многого другого.</p><p>Rails применяет архитектурный паттерн MVC (Model-View-Controller). Фреймворк хорош с точки зрения бизнес-логики и взаимодействует с базой данных с помощью ActiveRecord ORM.</p><p>Rails поставляется со встроенными инструментами и библиотеками. Например, ActiveRecord для работы с базами данных, ActiveStorage для управления файлами, ActionMailer для отправки email.</p><p>В сообществе Rails огромное количество гемов (библиотек), расширяющих функциональность фреймворка.</p><p>Пример модели Rails (с использованием ActiveRecord):</p><p>Пример контроллера Rails:</p><p>В примере определяем модель Article с валидациями и связями. Контроллер ArticlesController содержит экшены для списка статей, отображения отдельной статьи, создания новой статьи.  Приватный метод article_params используется для фильтрации параметров.</p><h4>Преимущества фреймворка:</h4><ul><li>Продуманная структура, которая продвигает стандарты качества и лучшие практики веб-разработки;</li><li>Active Record ORM упрощает взаимодействие с базой данных;</li><li>Vue, Angular.js и React легко интегрируются с Ruby on Rails.</li></ul><h4>Недостатки фреймворка:</h4><ul><li>Ruby on Rails js медленнее Django и Node.js.</li></ul><h3>Node.js с Express (JavaScript)</h3><p>Express — фреймворк Node.js с набором функций для разработки веб-приложений и API. В нем реализован простой интерфейс для HTTP-запросов и маршрутизации.</p><p>Node.js + Express используется для сервисов, серверных приложений (например, чатов или игр).</p><p>Преимущество Node.js и Express состоит в возможности писать на JavaScript как клиентскую, так и серверную сторону. Можно вести разработку на одном языке и делиться кодом с фронтендом и бэкендом.</p><p>Пример простого приложения на Express:</p><h4>Преимущества фреймворка:</h4><ul><li>JavaScript на всем стеке — один язык для фронтенда и бэкенда;</li><li>Имеет минимальные ограничения, можно строить архитектуру как удобно.</li></ul><h4>Недостатки фреймворка:</h4><ul><li>Отсутствуют встроенные компоненты, требуются дополнительные настройки для безопасности и работы с базами данных;</li><li>Управление обратными вызовами усложняет код и его поддержку.</li></ul><h2>Full-Stack фреймворки</h2><h3>Laravel (PHP)</h3><p>Laravel — фреймворк для веб-разработки на PHP. Он использует архитектуру MVC: разделяет логику приложения и улучшает организацию кода.</p><p>Laravel выбирают для разработки CMS, SaaS-платформ, электронной коммерции и др. Встроенные библиотеки ускоряют работу.</p><p>В фреймворке реализована:</p><ul><li>Система миграций для управления структурой базы данных;</li><li>Eloquent ORM для работы с данными;</li><li>Система шаблонизации Blade;</li><li>Встроенная поддержка аутентификации и авторизации;</li><li>Очередь заданий и планировщик для выполнения асинхронных задач.</li></ul><p>Пример определения маршрута в Laravel:</p><p>Пример контроллера Laravel:</p><p>Пример модели Eloquent:</p><p>В примерах выше определяем маршрут, который принимает id и возвращает строку с идентификатором. Контроллер UserController методом show получает пользователя из базы данных по id и передает его в представление user.profile. Модель User представляет таблицу пользователей в базе данных и определяет заполняемые атрибуты.</p><h4>Преимущества фреймворка:</h4><ul><li>Шаблонизатор Blade упрощает создание представлений;</li><li>ORM Eloquent облегчает работу с базами данных;</li><li>Есть автоматизация задач с помощью встроенных инструментов и командной строки.</li></ul><h4>Недостатки:</h4><ul><li>Сложности с долгосрочной поддержкой версий.</li></ul><h3>Spring Boot (Java)</h3><p>Spring Boot применяется для разработки микросервисов и облачных приложений. Модульная архитектура используется в независимых сервисах, которые легко масштабировать.</p><p>Фреймворк имеет встроенный контейнер сервлетов (Tomcat, Jetty), чтобы запускать приложение как автономный JAR-файл без развертывания на внешнем сервере.</p><p>Фреймворк также предлагает:</p><ul><li>Автоконфигурацию библиотек (JPA, JDBC);</li><li>Встроенные метрики мониторинга;</li><li>Поддержку внешней конфигурации;</li><li>Интеграцию с базами данных.</li></ul><h4>Преимущества фреймворка:</h4><ul><li>Есть встроенные серверы Tomcat, Jetty и Undertow;</li><li>Облегчает управление зависимостями с помощью стартовых пакетов;</li><li>Оснащен встроенным контейнером сервлетов;</li><li>Автоматическая конфигурация экономит время на старте проекта.</li></ul><h4>Недостатки:</h4><ul><li>Spring Boot создает множество неиспользуемых зависимостей и  увеличивает размер файла развертывания.</li></ul><h3>Meteor (JavaScript)</h3><p>Особенность Meteor в том, что он синхронизирует данные в реальном времени. Фреймворк автоматически обновляет пользовательский интерфейс при изменении данных на сервере. Это возможно благодаря протоколу DDP (Distributed Data Protocol) и реактивным источникам данных, таких как MongoDB.</p><p>На JS + Meteor можно писать код, который работает как на клиенте, так и на сервере. Фреймворк также предоставляет интегрированную систему сборки, которая автоматически объединяет ресурсы приложения.</p><p>Meteor выбирают для разработки приложений, требующих обновления данных в реальном времени (чаты, приложения для совместной работы, панели мониторинга,  игровые проекты). Его реактивная архитектура и синхронизация данных облегчают создание интерактивных и отзывчивых пользовательских интерфейсов.</p><h4>Преимущества фреймворка:</h4><ul><li>Архитектура и синтаксис с понятным кодом упрощают обучение новичков и повышают производительность команды;</li><li>Есть мгновенная синхронизация данных между клиентом и сервером;</li><li>Возможна интеграция базы данных MongoDB.</li></ul><h4>Недостатки фреймворка:</h4><ul><li>Не предлагает широкого функционала для масштабирования и разделения логики на модули;</li><li>Сложности с масштабированием при увеличении числа пользователей из-за обработки данных в реальном времени.</li></ul><p>При выборе фреймворка важно учитывать долгосрочные перспективы проекта. Также следует принимать во внимание доступность обучающих ресурсов и поддержки. Помните, нет идеального решения. Выбор фреймворка зависит от конкретных требований, ресурсов и предпочтений команды.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как оптимизировать SQL-запросы для снижения нагрузки на БД</title>
      <link>https://tproger.ru/articles/sovety-po-optimizacii-sql-zaprosov-dlya-snizheniya-nagruzki-na-bd</link>
      <comments>https://tproger.ru/articles/sovety-po-optimizacii-sql-zaprosov-dlya-snizheniya-nagruzki-na-bd?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sovety-po-optimizacii-sql-zaprosov-dlya-snizheniya-nagruzki-na-bd</guid>
      <description><![CDATA[<p>Узнайте, как оптимизировать SQL-запросы с помощью индексов, EXPLAIN и рефакторинга. Практические советы для снижения нагрузки на базу данных. Читайте на Tproger!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sovety-po-optimizacii-sql-zaprosov-dlya-snizheniya-nagruzki-na-bd">Как оптимизировать SQL-запросы для снижения нагрузки на БД</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 29 Nov 2024 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Современные системы управления базами данных (СУБД) ежедневно обрабатывают огромные дата-объёмы. Неправильно построенные SQL-запросы могут замедлить работу базы, создать избыточную нагрузку на сервер и снизить производительность приложений. Сегодня мы рассмотрим ключевые методы оптимизации SQL-запросов, принципы их построения и способы снижения нагрузки на БД.</p><h2>Использование индексов для ускорения запросов</h2><p>Индексы — это важный инструмент для оптимизации SQL-запросов, который позволяет значительно ускорить поиск данных и снизить нагрузку на базу. Они работают как указатель, который направляет СУБД к нужным строкам вместо того, чтобы сканировать всю таблицу. Оптимизация SQL-запросов с помощью индексов позволяет повысить производительность и сократить время выполнения сложных выборок.</p><h3>Что такое индексы и как они работают?</h3><p>Индекс — это дополнительная структура данных, созданная на основе столбцов таблицы. При добавлении индекса СУБД организует данные таким образом, чтобы ускорить операции чтения. Основной принцип работы индексов заключается в упрощении поиска с помощью упорядоченных структур, по типу B-деревьев.</p>]]></content:encoded>
    </item>
    <item>
      <title>Исследуем структуру базы данных MySQL с помощью функций SHOW</title>
      <link>https://tproger.ru/articles/issleduem-strukturu-bazy-dannyh-mysql-s-pomoshhyu-funkcij-show</link>
      <comments>https://tproger.ru/articles/issleduem-strukturu-bazy-dannyh-mysql-s-pomoshhyu-funkcij-show?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Slava Rozhnev]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/issleduem-strukturu-bazy-dannyh-mysql-s-pomoshhyu-funkcij-show</guid>
      <description><![CDATA[<p>Для эффективной работы, и разработчику и тестировщику работающих с базой данных важно иметь возможность исследовать все необходимые компоненты.  Рассмотрим как это сделать в MySQL при помощи выражений SHOW</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/issleduem-strukturu-bazy-dannyh-mysql-s-pomoshhyu-funkcij-show">Исследуем структуру базы данных MySQL с помощью функций SHOW</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 03 Apr 2024 07:30:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Любая база данных это сложный набор всевозможных компонентов: таблиц, индексов, представлений, функций, процедур и других элементов. Для эффективной работы, и разработчику и тестировщику работающих с чужой базой данных важно иметь возможность исследовать все необходимые компоненты. В базе данных MySQL для этой цели существует целое семейство функций SHOW. Давайте ознакомимся с некоторыми из них и поймем, как они могут помочь QA специалистам и программистам.</p><h2>1. SHOW DATABASES - "Покажи мне все свои хранилища"</h2><p>Первым делом, когда вы открываете MySQL, вы можете воспользоваться SHOW DATABASES, чтобы увидеть все доступные базы данных. Это как список папок на компьютере.</p><p>Пример ниже (и все следующие) с сайта <a href="https://sqlize.online/s/W5">sqlize.online</a></p><p>Как вы видите эта команда выводит список всех доступных вам баз данных. Если у вашего пользователя нет доступа к какой-то из баз то вы не увидите её в списке. Это нужно учесть при вашем исследовании.</p><h2>2. SHOW TABLES - "Покажи, что у тебя есть"</h2><p>Когда вы хотите узнать, какие таблицы существуют в определенной базе данных, просто используйте SHOW TABLES. Это похоже на просмотр содержимого папки на компьютере. Для того что бы получить список таблиц в нужной нам базе перед выполнением команды SHOW нужно выполнить USE dbname;</p><p>Таким образом мы получили список таблиц.</p><h2>3. SHOW COLUMNS - "Что у тебя внутри?"</h2><p>Если вам интересно, какие столбцы есть в таблице, просто воспользуйтесь SHOW COLUMNS. Так вы узнаете, какие данные вы можете там найти. Данная команда используется вместе с названием исследуемой таблицы следующим образом:</p><p>Данная команда возвращает более подробный результат. Вы видите не только наименования колонок но и их тип, возможность сохранения пустых значений (NULL) является ли поле ключевым, его значение по умолчанию и дополнительную информацию о колонке.</p><p>Данное исследование может дать нам ответ на вопрос: Почему я не могу добавить запись не указав название, или почему в поле last_update появилось значение которое я не указывал.</p><h2>4. SHOW INDEX - "Покажи мне твои секретные индексы"</h2><p>С SHOW INDEX вы можете посмотреть, какие индексы установлены в таблице. Это поможет вам понять, какие столбцы можно использовать для быстрого доступа к данным.</p><p>Здесь мы видим что таблица имеет первичный ключ по полю city_id а также не уникальный индекс по полю country_id. Этой информации нам будет достаточно чтобы понять что выборка из таблицы городов по идентификатору страны должна быть очень быстрой.</p><h2>5. SHOW CREATE TABLE - "Покажи, как создать это"</h2><p>Хотите узнать, как создать определенную таблицу? Просто используйте SHOW CREATE TABLE, и MySQL покажет вам SQL-запрос для создания таблицы.</p><p>Очень удобная штука! Таким образом вы видите всю структуру в компактном виде. Это удобно для сравнения структуры таблиц например на тестовом сервере и на боевом. Так же эта команда не заменив если кто-то просит вас показать DDL таблиц. Одна команда и всё готово. Кстати если вам нужно поделиться с коллегой  вы можете воспользоваться сайтом <a href="https://sqlize.online/s/t5">sqlize.online</a> - наберите или скопируйте свой SQL код, нажмите кнопку RUN чтобы код был выполнен системой, а затем кнопку SHARE, чтобы получить в буфер обмена короткую ссылку на ваш код. После этого любой, кто получит ссылку, сможет продолжить работать с вашим кодом!</p><p>В дополнение к SHOW CREATE TABLE вы можете использовать</p><p>то есть получить код создания любого объекта в базе данных</p><h2>6. SHOW TABLE STATUS - "Сколько у тебя строк?"</h2><p>Наконец, SHOW TABLE STATUS позволяет вам получить различную информацию о таблице, такую как количество строк или размер таблицы. Это полезно для оценки производительности и размера таблиц.</p><p>Из полученной таблицы мы можем извлечь массу полезной информации: когда была создана таблица, когда была изменена, сколько в ней строк и каково значение автоинкремента о котором я писал <a href="https://tproger.ru/articles/vse-chto-vy-hoteli-by-znat-ob-avtoinkremente-no-stesnyalis-sprosit">здесь</a>.  В общем ещё один ценный инструмент в руках исследователя!</p><h2>7. SHOW GRANTS - "Кто имеет доступ?"</h2><p>С помощью SHOW GRANTS можно узнать привилегии, предоставленные пользователям в MySQL. Это полезно для проверки безопасности и доступа к данным.</p><p>Если у вас достаточно привилегий в базе, то при помощи этой команды можно узнать, кто ещё может подключаться к базе и какие действия выполнять. Это очень полезная команда для сисадминов и пен-тестеров.</p><h2>8. SHOW MASTER / REPLICA STATUS - "Эй! Кто отстаёт?"</h2><p>Эта команда необходима в случае репликации для того чтобы понять всё ли с ней в порядке и если нет - насколько всё плохо.</p><h2>8. SHOW [GLOBAL] VARIABLES - "Покажи настройки"</h2><p>Данная команда позволяет увидеть параметры конфигурации базы данных. Если вам нужно выбрать только нужные из большого списка - отфильтруйте их при помощи LIKE как в примере ниже:</p><p>Эти значения могут помочь вам в оптимизации работы сервера. Далее без лишних подробностей перечислю ещё несколько полезных команд которыми мне приходилось пользоваться:</p><ul><li><a></a>SHOW ERRORS - показывает список ошибок.</li><li><a></a>SHOW ENGINE STATUS - статус движка базы данных - позволяет увидеть DEAD LOCKS</li></ul><p>Таким образом я привел список наиболее употребимых команд из целого класса <a href="https://dev.mysql.com/doc/refman/8.0/en/show.html">SHOW SATEMENTS</a>, которые могут сильно облегчить понимание устройства базы данных разработчиками и тестировщиками. Не стесняйтесь заглядывать в этот раздел команд если вам нужно вытащить какую либо информацию об имеющейся у вас базе.</p>]]></content:encoded>
    </item>
    <item>
      <title>Старый баг в MySQL. Детективная история</title>
      <link>https://tproger.ru/articles/staryj-bag-v-mysql-istoriya-detektiva</link>
      <comments>https://tproger.ru/articles/staryj-bag-v-mysql-istoriya-detektiva?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Slava Rozhnev]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/staryj-bag-v-mysql-istoriya-detektiva</guid>
      <description><![CDATA[<p>В этой статье я хочу описать баг, который я обнаружил в MySQL, и предостеречь вас от проблем, к которым он может привести.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/staryj-bag-v-mysql-istoriya-detektiva">Старый баг в MySQL. Детективная история</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Баги и ошибки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 24 Apr 2023 14:54:41 GMT</pubDate>
      <content:encoded><![CDATA[<p>В этой статье я хочу описать одну ошибку, которую я обнаружил в MySQL (не первый, но тем не менее), и предостеречь вас от проблем, к которым она может привести.</p><p>Один парень из моего чата в <a href="https://t.me/sqlize">Telegram </a>спросил меня: «Как я могу увидеть все внешние ключи, связанные с определенной таблицей?» Я дал ему быстрый ответ: «Посмотрите в `information_schema`». Я был полностью уверен в ответе, но всё равно решил убедиться лишний раз.</p><p>Я создал простую таблицу `test` и таблицу `ref1` с полем `test_id`, связанным с полем id:</p><p>Кажется, просто, потому что я люблю этот короткий синтаксис. После этого я посмотрел на таблицу информационной схемы `REFERENTIAL_CONSTRAINTS` и не нашел никаких записей.</p><p>Что за?! Это невероятно! Я люблю этот краткий синтаксис для создания внешних ключей и использовал его много раз!</p><p>Я создал еще одну связанную таблицу `ref2` используя стандартный синтаксис.</p><p>Снова проверил. И чудо свершилось! Я увидел запись в таблице `REFERENTIAL_CONSTRAINTS`. Как это возможно?</p><p>Я был разочарован и решил провести ещё один тест. Я подумал что возможно ограничение всё-таки создается, но только не отображается.</p><p>Теперь я думал, что если я попробую удалить первую строку из `test` то получу ошибку (я все еще сохраняю надежду на лучшее).</p><p>Но к моему ужасу MySQL спокойно удаляет эту строку без какого-либо предупреждения.  Как же так?! Мой мир рухнул. Я же постоянно использовал эту конструкцию в надежде, что целостность данных обеспечена.</p><p>Чтобы вернуть равновесие, делаю второй тест. Пытаюсь удалить вторую строку, связанную со второй таблицей.</p><p>И получаю долгожданную ошибку:</p><p>Итак, это не фича, это реальный БАГ!  MySQL позволяет создавать таблицы с использованием сокращенного синтаксиса без предупреждения, но ограничения не создаются и не защищают ваши данные от несогласованности.</p><p>Я поискал в Google и нашел <a href="https://bugs.mysql.com/bug.php?id=4919">открытую ошибку с 2004 года</a>, которую до сих пор не исправили. Ребята, что вы делаете?</p><p>Для своего душевного спокойствия я решил запустить этот тест на других базах данных и обнаружил, что все базы данных, на которых я мог проверить на <a href="https://sqlize.online/sql/mysql80/0295e1d928b15c3e54f5cadcda10a750/">SQLize.online</a>, позволяют использовать короткий синтаксис, и все они (MariaDB, PostgreSQL, SQL Server, Oracle) создают ограничения внешнего ключа в обоих случаях, кроме MySQL и SQLite.</p><p>Если Вам понравилась статья, Вы можете <a href="https://pay.cloudtips.ru/p/60214a3d">поддержать автора</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Обзор Prisma ORM — инструмента для работы с Node.js и TypeScript</title>
      <link>https://tproger.ru/articles/obzor-prisma-orm-instrumenta-dlja-raboty-s-node-js-i-typescript</link>
      <comments>https://tproger.ru/articles/obzor-prisma-orm-instrumenta-dlja-raboty-s-node-js-i-typescript?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Aleksei Kankov]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/obzor-prisma-orm-instrumenta-dlja-raboty-s-node-js-i-typescript</guid>
      <description><![CDATA[<p>Рассказываем, как работать с Prisma ORM. Это инструмент, который позволяет работать с базами данных SQL-типа на языках JS и TS.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/obzor-prisma-orm-instrumenta-dlja-raboty-s-node-js-i-typescript">Обзор Prisma ORM — инструмента для работы с Node.js и TypeScript</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Пост пользователя]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 30 Aug 2022 09:29:43 GMT</pubDate>
      <content:encoded><![CDATA[<p>В этой статье я хотел бы пройти по процессу установки и использованию Prisma ORM. У меня есть большой опыт использования различных ORM для реляционных баз данных с такими языками программирования как Python, TypeScript, JavaScript и PHP. Исходя из этого я опишу то, что мне нравится в этой библиотеке и что нет. Я буду использовать язык программирования TypeScript и MySQL в качестве базы данных. Yarn будет использоваться для инициализации проекта и управления зависимостями. Я не ожидаю каких-то глубоких знаний этих технологий и мои примеры будут по большей части объяснять сами себя.</p><h2>Установка Prisma ORM в новом проекте</h2><p>По большей части я буду использовать <a href="https://www.prisma.io/docs/getting-started/quickstart">официальную документацию</a>.</p><p>Давайте создадим проект и инициализируем его.</p><p>Добавим конфигурацию для TypeScript компилятора в tsconfig.json файл.</p><p>Установим Prisma ORM</p><p>Инициализация Prisma ORM для базы данных MySQL.</p><h2>Модель данных</h2><p>Prisma ORM использует несколько нестандартный подход к модели данных. Для того чтобы определить модели, необходимо использовать специальный файл и специфичный для этой библиотеки синтаксис. Он несколько менее гибок, чем моделирование при помощи аннотаций в *.ts файлах, но при этом легче читается. Большая часть типов данных, поддерживаемая в различных базах данных имеет поддержку в Prisma ORM, но в то же время есть ряд исключений, которые могут повлиять на выбор библиотеки для работы с данными.</p><p>На основании схемы Prisma ORM автоматически сгенерирует код для модели данных и миграции, для изменения базы данных.</p><h2>Простые запросы к базе данных</h2><p>Следующий скрипт позволяет сразу создать новый аккаунт и пост. Prisma ORM клиент позволяет создавать одновременно несколько связанных сущностей в одной транзакции, что облегчает работу со связанными сущностями.</p><p>Я настоятельно рекомендую включать логирование запросов к базе данных при разработке приложения. Это поможет отслеживать реальные запросы и понять какие запросы выполняются быстрее или медленнее. Конкретный пример я приведу ниже</p><p>Следующий запрос достанет из базы данных все активные аккаунты. В нашей безе есть всего лишь один аккаунт, поэтому такой запрос безопасен. В случае большой базы данных необходимо разбивать результат на страницы для избежания переполнения памяти.</p><h2>Использование «сырых» запросов</h2><p>Теперь давайте достанем из базы первые 10 уникальных имен аккаунтов.</p><p>Код выглядит довольно просто. Но нас ожидает сюрприз в логах. SQL запрос к базе данных выглядит следующим образом:</p><p>Как вы видите, в этом запросе не используются лимиты, прописанные в запросе. Это потому, что Prisma не использует `DISTINCT` в запросах и фильтрует данные в памяти. Это крайне сомнительное решение. Оно будет работать когда в базе есть несколько тысяч записей, но перестанет если там будет несколько миллионов. Да и вообще крайне странно доставать из базы миллион записей для того, чтобы отфильтровать первые 10 уникальных имен.</p><p>В этом случае необходимо уже спускаться на уровень «сырых» запросов к базе данных.</p><p>Полученный SQL запрос:</p><p>На первый взгляд код из этого примера выглядит как классический пример из книги «Как сделать SQL инъекцию». Но на самом деле это не так. Под капотом Prisma делает немного магии, которая позволяет избежать уязвимостей.</p><p>Результат следующего кода это не просто строка с подставленными в нее значениями переменных. Prisma генерирует объект с запросом и параметрами этого запроса.</p><p>Все переменные заменены на плейсхолдеры и поэтому такой запрос безопасен. В то же время такой подход может вызвать проблемы при составлении более сложных запросов. Пример я приведу в следующем разделе.</p><h2>«Сырые» небезопасные запросы</h2><p>Представьте себе ситуацию, в которой вам нужно фильтровать данные по полям из JSON объекта `meta`. При этом, то, по каким полям производить фильтрацию тоже определяется на уровне кода.</p><p>Полученный запрос работать не будет. В этом случае эта магия, которая работает под капотом `Prisma.sql` не позволит нам просто взять и собрать запрос из нескольких строк.</p><p>Поэтому пришло время для использования `$queryRawUnsafe`. Мы все еще будем использовать параметры в запросе для значений JSON полей и лимитов</p><p>Полученный SQL:</p><p>Этот запрос выглядит довольно неплохо, но все же я крайне не рекомендую использовать его в реальной работе. Он никогда не будет использовать индексы в вашей базе и поэтому всегда будет выполняться медленно.</p><h2>Выводы</h2><p>В целом Prisma ORM — это неплохой выбор для проекта. Можно подчеркнуть, что не хватает возможности на уровне построителя запросов сделать `distinct`, но при этом достаточно просто двинуться в сторону «сырых» запросов к базе данных.</p>]]></content:encoded>
    </item>
    <item>
      <title>Собираем и деплоим приложение на Node.js с помощью werf. Работа с базой данных</title>
      <link>https://tproger.ru/articles/sobiraem-i-deploim-prilozhenie-na-node-js-s-pomoshhju-werf-rabota-s-bazoj-dannyh</link>
      <comments>https://tproger.ru/articles/sobiraem-i-deploim-prilozhenie-na-node-js-s-pomoshhju-werf-rabota-s-bazoj-dannyh?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Константин Нежберт]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sobiraem-i-deploim-prilozhenie-na-node-js-s-pomoshhju-werf-rabota-s-bazoj-dannyh</guid>
      <description><![CDATA[<p>Как в MySQL добавить Node.js приложение, развернуть базу данных в кластере, как правильно инициализировать её и выполнить миграции.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sobiraem-i-deploim-prilozhenie-na-node-js-s-pomoshhju-werf-rabota-s-bazoj-dannyh">Собираем и деплоим приложение на Node.js с помощью werf. Работа с базой данных</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Пост пользователя]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 15 Aug 2022 11:40:16 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://tproger.ru/articles/kubernetes-node-js-werf/">В прошлый раз</a> мы рассмотрели базовое Node.js-приложение и его деплой в Kubernetes. Теперь мы дополним его, подключив к нему базу данных. В качестве последней будем использовать MySQL, добавив в приложение необходимые для работы с ней компоненты, развернем БД в кластере, а также рассмотрим, как правильно инициализировать базу и выполнить миграции.</p><h2>Подготовка окружения</h2><p>Перед работой убедитесь, что у вас установлена актуальная версия werf из стабильной ветки. В случае, если вы еще не устанавливали werf, сделайте это <a href="https://ru.werf.io/installation.html">по официальной инструкции</a>.</p><p>Инструкции из статьи полностью совместимы и тестировались на операционной системе Linux Ubuntu 20.04.03. Для ОС других семейств, таких как macOS или Windows, могут быть отличия. Подробнее с ними можно ознакомиться <a href="https://ru.werf.io/guides/nodejs/200_real_apps.html">в официальной документации</a> к werf.</p><p>Также убедитесь, что у на вашем компьютере запущен кластер minikube, в котором подготовлено пространство имён werf-first-app. Если вы уже выполняли инструкции из первой статьи, то достаточно только запустить кластер следующей командой:</p><p>А затем установить пространство имён по умолчанию:</p><p>Если же вы впервые устанавливаете werf и проходите инструкции, то полное руководство по настройке minikube можно найти <a href="https://tproger.ru/articles/kubernetes-node-js-werf/">в главе «Предварительная настройка окружения»</a> предыдущей статьи.</p><h2>Подключение базы данных</h2><h3>Доработка приложения</h3><p>На текущий момент у нас есть stateless-приложение, то есть оно не использует БД и не хранит в ней никаких данных. В реальности такое случается нечасто, поэтому давайте доработаем его до stateful, добавив поддержку MySQL.</p><p>Основные изменения, которые мы произведем далее:</p><ol><li>Добавим зависимости, необходимые для взаимодействия с MySQL.</li><li>Настроим конфигурацию для соединения с БД.</li><li>Создадим миграцию и модель схемы БД.</li><li>Создадим маршруты в приложении, по которым будет происходить сохранение и чтение данных.</li></ol><p>Установим зависимости, требуемые для работы с БД:</p><p>Здесь мы добавили следующие пакеты:</p><ul><li>sequelize — ORM, обеспечивающий работы с БД;</li><li>mysql2 — драйвер MySQL;</li><li>express-async-handler — расширение контроллеров запросов, позволяющее работать с async/await;</li><li>sequelize-cli — утилита, позволяющая генерировать миграции и модели.</li></ul><p>Чтобы sequelize мог работать, мы создали для него конфигурационный файл .sequelizerc, в котором задали параметры подключения к БД, а также структуру файлов самого sequelize. Все директории, имеющие отношение в БД, мы определили в каталог db, а конигурацию в файл config/database.json.</p><h3>Добавление endpoint’ов</h3><p>Чтобы убедиться, что приложение и правда умеет обращаться к БД, добавим ему пару новых endpoint’ов — <b>/remember</b> и <b>/say</b> — первый будет записывать данные в БД, а другой извлекать и показывать. В каталоге <b>routes</b> добавим файл <b>talkers.js</b>:</p><p>Сгенерируем модель и миграцию БД с помощью команды:</p><p>Модель можно посмотреть в файле db/models/talker.js:</p><p>Также автоматически была сгенерирована миграция для новой модели, расположенная в файле db/migrations/20211101064002-create-talker.js:</p><p>Осталось создать новые маршруты в файле app.js:</p><p>Приложение подготовлено и готово к запуску!</p><h3>Разворачиваем MySQL</h3><p>В реальных условиях БД можно поднять как внутри кластера Kubernetes, так и за его пределами. При использовании внешней базы доступны различные варианты: от собственной базы, развернутой на своей инстраструктуре, до managed-решений наподобие Amazon RDS.</p><p>В качестве примера с нашим приложением мы развернем базу данных MySQL внутри кластера, воспользовавшись типом ресурсов StatefulSet. Для этого создадим файл .helm/templates/database.yaml со следующими параметрами:</p><p>Теперь настроим наше приложение на подключение к созданной БД. Стоит отметить, что Sequelize ожидает определения подключения для всех окружений в единственном файле — config/database.json. Пропишем в нем нужные параметры:</p><h3>Инициализация БД</h3><p>Развернуть MySQL — это еще половина дела. Далее следует ее правильно инициализировать, проведя нужные миграции и дождавшись ее готовности к работе.</p><p>В Kubernetes есть несколько проверенных способов для развертывания и инициализации базы данных. Один из них — использование отдельной Job’ы одновременно с разввертыванием основного приложения. В ней будут выполнять все необходимые для инициализации действия.</p><p>Очень важно соблюсти правильный порядок развертывания ресурсов, поэтому мы будем следовать двум правилам:</p><ul><li>Job’а должна убедиться, что база доступна, и только затем выполнить миграции;</li><li>приложение ожидает перед запуском следующего, что:</li></ul><ol><li>БД доступна;,</li><li>БД подготовлена и готова к работе;,</li><li>миграции выполнены.</li></ol><p>При соблюдении этих правил все компоненты создаются одновременно, но функционировать начнут в заданном порядке:</p><ol><li>Поднимается БД;</li><li>Выполнятся миграции и инициализация с помощью Job’ы.</li><li>Стартанут приложения..</li></ol><p>Приступим к реализации. Для начала добавим Job (.helm/templates/job-db-setup-and-migrate.yaml), которая будет заниматься инициализацией и миграциями БД:</p><p>Следует пояснить, почему мы ожидаем целых десять проверок БД. Если этого не сделать, то mysqladmin ping выполнится всего один раз перед тем, как StatefusSet с MySQL начнет перезапускаться при деплое. При этом база данные окажется недоступна.</p><p>Дополнительно следует обратить внимание, что при первом запуске основной процесс MySQL может перезапуститься несколько раз без перезапуска самого контейнера. Это может привести к ситуации, когда БД ушла в перезапуск, а Job’а уже начала выполнять миграции. Последние при этом само собой будут неудачными, и весь процесс разворачивания закончится ошибкой.</p><p>Число 10 здесь выбрано просто как пример, его можно изменять в зависимости от ситуации.</p><p>В Deployment’е также необходимо внести изменения, добавив проверку доступности БД перед тем, как стартовать приложение:</p><p>Все готово, можно запускать.</p><h2>Проверка работоспособности</h2><p>Выполним команду ниже, чтобы запустить процесс деплоя:</p><p>Мы должны увидеть примерно следующее:</p><p>Обратите внимание, что не стоит пугаться сообщений об ошибках, если они появятся. Это говорит лишь о том, что Sequelize не смог подключиться к базе данных, потому что они еще не создана (не прошли миграции). Нужно просто подождать, и все заработает.</p><p>Проверим, что все работает как нужно. Попробуем обратиться на /say:</p><p>Так как в базе данных пока ничего нет, мы увидим ответ:</p><p>Добавим туда данные, воспользовавшись /remember:</p><p>Если все прошло успешно, получим ответ:</p><p>Еще раз прочитаем данные из БД:</p><p>Ожидаемый результат в случае успеха:</p><p>Убедимся, что текст, который мы увидели, взят прямо из базы данных. Посмотрим содержимое таблицы talkers напрямую:</p><p>Мы должны увидеть табличку с нашим текстом:</p><p>Все работает! Наше приложение стало stateful. Подобный подход к взаимодействию с базами данных аналогичен с любыми другими БД, не только с MySQL.</p><h2>Заключение</h2><p>Мы посмотрели на пример развертывания в кластере MySQL, ее инициализации, выполнение миграций, а также настроили наше приложение на подключение и использование базы данных.</p><p>В основе этой статьи лежит наш <a href="https://ru.werf.io/guides.html">онлайн-самоучитель</a>. В ней рассказано не все, более подробные инструкции или теорию можно найти в полной версии самоучителя, в разделе «<a href="https://ru.werf.io/guides/nodejs/100_basic.html">Реалистичные приложения</a>».</p><p>Надеемся, что эта статья окажется полезной для вас в части приобретения нового опыта в области деплоя приложений в Kubernetes.</p><p>Ждем вас в комментариях к статье, а также в <a href="https://t.me/werf_ru">Telegram-каналe werf_ru</a>. Мы всегда рады оказать вам любое содействие на этом трудном пути. Также не забывайте про <a href="https://github.com/werf/werf">GitHub-репозиторий werf</a>, там всегда будут рады любым issues (и звездам).</p>]]></content:encoded>
    </item>
    <item>
      <title>Основные команды SQL, которые должен знать каждый программист</title>
      <link>https://tproger.ru/translations/sql-recap</link>
      <comments>https://tproger.ru/translations/sql-recap?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Кирилл Поздеев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/sql-recap</guid>
      <description><![CDATA[<p>Основные команды SQL с примерами на MySQL: SELECT, JOIN, GROUP BY, ORDER BY, WHERE, подзапросы и агрегатные функции. Сохраните как шпаргалку для работы.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/sql-recap">Основные команды SQL, которые должен знать каждый программист</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 10 Dec 2020 09:30:05 GMT</pubDate>
      <content:encoded><![CDATA[<p>Основные команды SQL не ограничиваются стандартными CREATE, UPDATE и DELETE. Данная статья будет полезна тем, кто хочет <a href="https://tproger.ru/articles/sql-interview-questions/">освежить свои знания по SQL перед собеседованием на работу</a>.</p><p>Обратите внимание, что в примерах используется MySQL, поэтому в конце каждого оператора ставится точка с запятой. Если вы только начинаете знакомство с реляционными базами данных, также рекомендуем наш материал <a href="https://tproger.ru/articles/osnovy-postgresql-dlya-nachinayushhih--ot-ustanovki-do-pervyh-zaprosov-250851">«Основы PostgreSQL для начинающих»</a>. Эта статья — часть нашего <a href="https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij">полного путеводителя по SQL</a>.</p><p>Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.</p><h2>Настройка базы данных</h2><p>Перед началом создайте БД с тестовыми данными. Для работы вам понадобится скачать два файла: <a href="https://drive.google.com/file/d/0B_oq3-doZhC-ME1lUlR3a3pYRU0/view?resourcekey=0-flfPMq0i6E6-i5BX27Se4g">DLL.sql</a> и <a href="https://drive.google.com/file/d/0B_oq3-doZhC-TV9ud1JubkVDaXM/view?resourcekey=0-CToHONw06G5QQ6DuRf68Ng">InsertStatements.sql</a>. После установите MySQL, откройте терминал и войдите в консоль MySQL с помощью команды:</p><p>Затем введите пароль и выполните следующую команду. Назовём базу данных «university»:</p><h2>SHOW DATABASES</h2><p>SQL-команда, которая отвечает за просмотр доступных баз данных.</p><h2>CREATE DATABASE</h2><p>Команда для создания новой базы данных.</p><h2>USE</h2><p>С помощью этой SQL-команды USE &lt;database_name&gt; выбирается база данных, необходимая для дальнейшей работы с ней.</p><h2>SOURCE</h2><p>А SOURCE &lt;file.sql&gt; позволит выполнить сразу несколько SQL-команд, содержащихся в файле с расширением .sql.</p><h2>DROP DATABASE</h2><p>Стандартная SQL-команда для удаления целой базы данных.</p><h2>SHOW TABLES</h2><p>С помощью этой несложной команды можно увидеть все таблицы, которые доступны в базе данных.</p><h2>CREATE TABLE</h2><p>SQL-команда для создания новой таблицы:</p><h4>Ограничения целостности при использовании CREATE TABLE</h4><p>Может понадобиться создать ограничения для определённых столбцов в таблице. При создании таблицы можно задать следующие ограничения:</p><ul><li>ячейка таблицы не может иметь значение NULL;</li><li>первичный ключ — PRIMARY KEY(col_name1, col_name2, …);</li><li>внешний ключ — FOREIGN KEY(col_namex1, …, col_namexn) REFERENCES table_name(col_namex1, …, col_namexn).</li></ul><p>Можно задать больше одного первичного ключа. В этом случае получится составной первичный ключ.</p><h4>Пример</h4><p>Создайте таблицу «instructor»:</p><h2>DESCRIBE</h2><p>С помощью DESCRIBE &lt;table_name&gt; можно просмотреть различные сведения (тип значений, является ключом или нет) о столбцах таблицы.</p><h2>INSERT</h2><p>Команда INSERT INTO &lt;table_name&gt; в SQL отвечает за добавление данных в таблицу:</p><p>При добавлении данных в каждый столбец таблицы не требуется указывать названия столбцов.</p><h2>UPDATE</h2><p>SQL-команда для обновления данных таблицы:</p><h2>DELETE</h2><p>SQL-команда DELETE FROM &lt;table_name&gt; используется для удаления данных из таблицы.</p><h2>DROP TABLE</h2><p>А так можно удалить всю таблицу целиком.</p><h2>SELECT</h2><p>Далее мы рассмотрим основные команды SQL, которые позволяют работать непосредственно с данными. К одной из таких SQL-команд относится SELECT для получения данных из выбранной таблицы:</p><p>Следующей командой можно вывести все данные из таблицы:</p><h2>SELECT DISTINCT</h2><p>В столбцах таблицы могут содержаться повторяющиеся данные. Используйте SELECT DISTINCT для получения только неповторяющихся данных.</p><h2>WHERE</h2><p>Можно использовать ключевое слово WHERE в SELECT для указания условий в запросе:</p><p>В запросе можно задавать следующие условия:</p><ul><li>сравнение текста;</li><li>сравнение численных значений;</li><li>логические операции AND (и), OR (или) и NOT (отрицание).</li></ul><h4>Пример</h4><p>Попробуйте выполнить следующие команды. Обратите внимание на условия, заданные в WHERE:</p><figure><img src="https://media.tproger.ru/uploads/2018/09/6.png" alt="" /><figcaption>SQL-команды: пример вывода с WHERE</figcaption></figure><h2>GROUP BY</h2><p>Оператор GROUP BY часто используется с агрегатными функциями, такими как COUNT, MAX, MIN, SUM и AVG, для группировки выходных значений. Следующий шаг после базовых команд — <a href="https://tproger.ru/translations/sql-window-functions">оконные функции</a>.</p><h4>Пример</h4><p>Выведем количество курсов для каждого факультета:</p><figure><img src="https://media.tproger.ru/uploads/2018/09/7.png" alt="" /><figcaption>SQL-команды: пример вывода с GROUP BY</figcaption></figure><h2>HAVING</h2><p>Ключевое слово HAVING было добавлено в SQL по той причине, что WHERE не может использоваться для работы с агрегатными функциями.</p><h4>Пример</h4><p>Выведем список факультетов, у которых более одного курса:</p><figure><img src="https://media.tproger.ru/uploads/2018/09/8.png" alt="" /><figcaption>SQL-команды: пример вывода с HAVING</figcaption></figure><h2>ORDER BY</h2><p>ORDER BY используется для сортировки результатов запроса по убыванию или возрастанию. ORDER BY отсортирует по возрастанию, если не будет указан способ сортировки ASC или DESC. Подробнее о возможностях сортировки — в нашем <a href="https://tproger.ru/articles/sql---eto-prosto--chast-vtoraya--sortiruem-">гайде по ORDER BY и сортировке данных</a>.</p><h4>Пример</h4><p>Выведем список курсов по возрастанию и убыванию количества кредитов:</p><h2>BETWEEN</h2><p>BETWEEN используется для выбора значений данных из определённого промежутка. Могут быть использованы числовые и текстовые значения, а также даты.</p><h4>Пример</h4><p>Выведем список инструкторов, чья зарплата больше 50 000, но меньше 100 000:</p><h2>LIKE</h2><p>Оператор LIKE используется в WHERE, чтобы задать шаблон поиска похожего значения.</p><p>Есть два свободных оператора, которые используются в LIKE:</p><ul><li>% (ни одного, один или несколько символов);</li><li>_ (один символ).</li></ul><h4>Пример</h4><p>Выведем список курсов, в имени которых содержится «to», и список курсов, название которых начинается с «CS-»:</p><figure><img src="https://media.tproger.ru/uploads/2018/09/11.png" alt="" /><figcaption>SQL-команды: пример вывода с LIKE</figcaption></figure><h2>IN</h2><p>С помощью IN можно указать несколько значений для оператора WHERE:</p><h4>Пример</h4><p>Выведем список студентов с направлений Comp. Sci., Physics и Elec. Eng.:</p><h2>JOIN</h2><p>JOIN используется для связи двух или более таблиц с помощью общих атрибутов внутри них. На изображении ниже показаны различные способы объединения в SQL. Обратите внимание на разницу между левым внешним объединением и правым внешним объединением:</p><figure><img src="https://media.tproger.ru/uploads/2018/09/13.jpg" alt="" /><figcaption>SQL-команды: схема использования JOIN</figcaption></figure><h4>Пример</h4><p>Выведем список всех обязательных курсов и детали о них:</p><figure><img src="https://media.tproger.ru/uploads/2018/09/15.png" alt="" /><figcaption>SQL-команды: пример вывода с JOIN</figcaption></figure><h2>VIEW</h2><p>VIEW — это виртуальная таблица SQL, созданная в результате выполнения выражения. Она содержит строки и столбцы и очень похожа на обычную SQL-таблицу. VIEW всегда показывает самую свежую информацию из базы данных.</p><h4>Создание</h4><h4>Удаление</h4><h2>Агрегатные функции</h2><p>Это не совсем основные команды SQL, однако знать их тоже желательно. Агрегатные функции используются для получения совокупного результата, относящегося к рассматриваемым данным. Правильное использование агрегатных функций напрямую влияет на производительность — читайте <a href="https://tproger.ru/articles/sovety-po-optimizacii-sql-zaprosov-dlya-snizheniya-nagruzki-na-bd">советы по оптимизации SQL-запросов</a>.</p><ul><li>COUNT(col_name) — возвращает количество строк;</li><li>SUM(col_name) — возвращает сумму значений в данном столбце;</li><li>AVG(col_name) — возвращает среднее значение данного столбца;</li><li>MIN(col_name) — возвращает наименьшее значение данного столбца;</li><li>MAX(col_name) — возвращает наибольшее значение данного столбца.</li></ul><h2>Вложенные подзапросы</h2><p>Вложенные подзапросы — это SQL-запросы, которые включают выражения SELECT, FROM и WHERE, вложенные в другой запрос.</p><h4>Пример</h4><p>Найдём курсы, которые преподавались осенью 2009 и весной 2010 годов:</p><h2>Часто задаваемые вопросы</h2><h3>Чем отличается WHERE от HAVING в SQL?</h3><p>WHERE фильтрует отдельные строки до группировки и не может работать с агрегатными функциями. HAVING применяется после GROUP BY и позволяет задавать условия для агрегированных значений, например HAVING COUNT(*) &gt; 5. На практике WHERE отсекает ненужные данные на раннем этапе, а HAVING фильтрует уже сгруппированные результаты.</p><h3>Какие SQL-команды нужно знать джуниору?</h3><p>Минимальный набор для начинающего разработчика: SELECT, INSERT, UPDATE, DELETE, WHERE, JOIN, GROUP BY и ORDER BY. Этого достаточно для большинства повседневных задач. По мере роста стоит освоить подзапросы, оконные функции и индексы — <a href="https://tproger.ru/articles/dorozhnaya-karta-obucheniya-sql-dlya-dostizheniya-urovnya-middle-">дорожная карта изучения SQL до уровня middle</a> поможет выстроить план обучения.</p><h3>В чём разница между INNER JOIN и LEFT JOIN?</h3><p>INNER JOIN возвращает только те строки, которые имеют совпадения в обеих таблицах. LEFT JOIN возвращает все строки из левой таблицы и совпадающие строки из правой; если совпадения нет, правая часть заполняется значениями NULL. Выбирайте LEFT JOIN, когда нужно сохранить все записи из основной таблицы, даже если связанных данных нет.</p><h3>Как оптимизировать медленные SQL-запросы?</h3><p>Начните с анализа плана выполнения через EXPLAIN — он покажет, какие операции занимают больше всего времени. Добавьте индексы на столбцы, используемые в WHERE, JOIN и ORDER BY — подробнее об этом в статье <a href="https://tproger.ru/articles/sql-indeksy-za-10-minut">SQL-индексы за 10 минут</a>. Избегайте SELECT *, выбирайте только нужные столбцы и используйте LIMIT для ограничения результатов. Готовитесь к собеседованию? <a href="https://tproger.ru/articles/sql-interview-questions">27 типовых вопросов по SQL</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>27 распространённых вопросов по SQL с собеседований и ответы на них</title>
      <link>https://tproger.ru/articles/sql-interview-questions</link>
      <comments>https://tproger.ru/articles/sql-interview-questions?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Картофельный Повелитель]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sql-interview-questions</guid>
      <description><![CDATA[<p>Подборка из 27 вопросов и задач по SQL, которые чаще всего задают на собеседованиях. Теория, практика, примеры запросов и ответы. Готовьтесь эффективно!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sql-interview-questions">27 распространённых вопросов по SQL с собеседований и ответы на них</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Собеседование]]></category>
      <category><![CDATA[NoSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 21 Aug 2020 11:50:13 GMT</pubDate>
      <content:encoded><![CDATA[<p>• Статья охватывает 27 ключевых вопросов по SQL: от теории (ключи, JOIN, ограничения) до практики (подзапросы, агрегатные функции)
• Каждый ответ содержит пример SQL-запроса, который можно сразу проверить
• Теоретическая часть покрывает СУБД, нормализацию, типы соединений и ограничения
• Практическая часть включает реальные задачи: поиск дублей, работу с датами, подзапросы</p><p>Вопросы по SQL на собеседованиях — обычное дело, и чтобы не завалиться, нужно хорошо понимать, как работать с базами данных. В этом списке представлены основные вопросы и задачи по SQL, которые часто встречаются на собеседованиях, а также ответы на них. Если вы готовитесь к интервью на Junior-позицию, также загляните в <a href="https://tproger.ru/articles/junior-developer-should-know">общий список вопросов для джуна</a>. Для системного изучения SQL рекомендуем <a href="https://tproger.ru/articles/dorozhnaya-karta-obucheniya-sql-dlya-dostizheniya-urovnya-middle-">дорожную карту SQL</a>.</p><h2>Теория</h2><h3>Что такое СУБД?</h3><p>Допустим, есть большая база данных, которой пользуются многие сотрудники: кто-то ищет информацию, а кто-то изменяет или даже удаляет её. Чтобы правильно обрабатывать все эти запросы, нужно специальное программное обеспечение, и именно такое ПО получило название системы управления базами данных (СУБД). Эта статья — часть нашего <a href="https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij">полного путеводителя по SQL</a>.</p><h3>Какие типы СУБД в соответствии с моделями данных вы знаете?</h3><p>Этот вопрос по SQL предполагает не просто назвать, но и дать краткое описание каждому типу.Существует <a href="https://tproger.ru/translations/sql-nosql-database-models/">несколько типов СУБД</a>:</p><ol><li>Реляционные, которые поддерживают установку связей между таблицами с помощью первичных и внешних ключей. Пример — MySQL.Flat File — базы данных с двумерными файлами, в которых содержатся записи одного типа и отсутствует связь с другими файлами, как в реляционных. Пример — Excel.Иерархические подразумевают наличие записей, связанных друг с другом по принципу отношений один-к-одному или один-ко-многим. А вот для отношений многие-ко-многим следует использовать реляционную модель. Пример — Adabas.Сетевые похожи на иерархические, но в этом случае «ребёнок» может иметь несколько «родителей» и наоборот. Примеры — IDS и IDMS.Объектно-ориентированные СУБД работают с базами данных, которые состоят из объектов, используемых в ООП. Объекты группируются в классы и называются экземплярами, а классы в свою очередь взаимодействуют через методами. Пример — Versant.Объектно-реляционные обладают преимуществами реляционной и объектно-ориентированной моделей. Пример — IBM Db2.Многомерная модель является разновидностью реляционной и использует многомерные структуры. Часто представляется в виде кубов данных. Пример — Oracle Essbase.Гибридные состоят из двух и более типов баз данных. Используются в том случае, если одного типа недостаточно для обработки всех запросов. Пример — Altibase HDВ.</li></ol><h3>Что такое первичный ключ?</h3><p>Первичный ключ или PRIMARY KEY предназначен для однозначной идентификации каждой записи в таблице и является строго уникальным (UNIQUE): две записи таблицы не могут иметь одинаковые значения первичного ключа. Нулевые значения (NULL) в PRIMARY KEY не допускаются. Если в качестве PRIMARY KEY используется несколько полей, их называют составным ключом.Пример:</p><p>Здесь в качестве первичного ключа используется поле id.</p><h3>Когда используется PRIMARY KEY?</h3><p>PRIMARY KEY — это первичный ключ, который используется в качестве основного ключа и может быть использован для связи с дочерней таблицей, содержащей внешний ключ.</p><h3>А что такое внешний ключ?</h3><p>Внешний ключ или FOREIGN KEY также является атрибутом ограничения и обеспечивает связь двух таблиц. По сути, это поле или несколько полей, которые ссылаются на PRIMARY KEY в родительской таблице.Пример использования:</p><p>В данном случае внешний ключ, привязанный к полю user_id в таблице order, ссылается на первичный ключ id в таблице users, и именно по этим полям происходит связывание двух таблиц.</p><h3>Какие ещё ограничения вы знаете, как они работают и указываются?</h3><p>SQL-ограничения (constraints) указываются при создании или изменении таблицы. Это правила для ограничения типа данных, которые могут храниться в таблице. Действие с данными не будет выполнено, если нарушаются установленные ограничения.</p><ul><li>UNIQUE — гарантирует уникальность значений в столбце;</li><li>NOT NULL — значение не может быть NULL;</li><li>INDEX — создаёт индексы в таблице для быстрого поиска/запросов;</li><li>CHECK — значения столбца должны соответствовать заданным условиям;</li><li>DEFAULT — предоставляет столбцу значения по умолчанию&amp;</li></ul><h3>Для чего используется ключевое слово ORDER BY?</h3><p>Для сортировки данных в порядке возрастания (ASC) или убывания (DESC).Пример использования:</p><p>Выбираются пользователи, которые будут отсортированы по имени в порядке убывания. Дополните ответ на этот вопрос по SQL тем, что без указания DESC данные были бы отсортированы по умолчанию — в порядке возрастания. Подробнее о сортировке читайте в статье <a href="https://tproger.ru/articles/sql---eto-prosto--chast-vtoraya--sortiruem-">SQL — сортировка данных</a>.</p><h3>Назовите четыре основных типа соединения в SQL</h3><p>Чтобы объединить две таблицы в одну, следует использовать оператор JOIN. Соединение таблиц может быть внутренним (INNER) или внешним (OUTER), причём внешнее соединение может быть левым (LEFT), правым (RIGHT) или полным (FULL).</p><ul><li>INNER JOIN — получение записей с одинаковыми значениями в обеих таблицах, т.е. получение пересечения таблиц.</li><li>FULL OUTER JOIN — объединяет записи из обеих таблиц (если условие объединения равно true) и дополняет их всеми записями из обеих таблиц, которые не имеют совпадений. Для записей, которые не имеют совпадений из другой таблицы, недостающее поле будет иметь значение NULL.</li><li>LEFT JOIN — возвращает все записи, удовлетворяющие условию объединения, плюс все оставшиеся записи из внешней (левой) таблицы, которые не удовлетворяют условию объединения.</li><li>RIGHT JOIN — работает точно так же, как и левое объединение, только в качестве внешней таблицы будет использоваться правая.</li></ul><figure><img src="https://media.tproger.ru/uploads/2020/08/DFDFD.jpg" alt="" /></figure><p>Рассмотрим пример соединения SQL таблиц с использованием INNER JOIN. Следующий запрос выбирает все заказы с информацией о клиенте:</p><h3>А что такое Self JOIN?</h3><p>Такой вопрос тоже может прозвучать на собеседовании по SQL. Это выражение используется для того, чтобы таблица объединилась сама с собой, словно это две разные таблицы. Чтобы такое реализовать, одна из таких «таблиц» временно переименовывается.Например, следующий SQL-запрос объединяет клиентов из одного города:</p><h3>Для чего нужен оператор UNION?</h3><p>Он используется для объединения полученных данных из двух или более запросов, которые должны иметь одинаковое количество столбцов с одинаковыми типами данных и расположенных в том же порядке.Пример использования:</p><h3>Как работают подстановочные знаки?</h3><p>Это специальные символы, которые нужны для замены каких-либо знаков в запросе. Они используются вместе с оператором LIKE, с помощью которого можно отфильтровать запрашиваемые данные.</p><h3>Какими бывают подстановочные знаки?</h3><ul><li>% — заменить ноль или более символов;</li><li>_ — заменить один символ.</li></ul><p>Примеры:</p><p>Данный запрос позволяет найти данные всех пользователей, имена которых содержат в себе «test».</p><p>А в этом случае имена искомых пользователей начинаются на «t», после содержат какой-либо символ и «est» в конце. Ещё практика — <a href="https://tproger.ru/articles/5-zadanij-po-sql-s-realnyh-sobesedovanij">5 заданий с реальных собеседований</a>.</p><h3>Что делают псевдонимы Aliases?</h3><p>SQL-псевдонимы нужны для того, чтобы дать временное имя таблице или столбцу. Это нужно, когда в запросе есть таблицы или столбцы с неоднозначными именами. В этом случае для удобства в составлении запроса используются псевдонимы. SQL-псевдоним существует только на время запроса.Пример:</p><h3>Для чего нужен оператор INSERT INTO SELECT?</h3><p>Данный оператор копирует данные из одной таблицы и вставляет их в другую, при этом типы данных в обеих таблицах должны соответствовать.Пример использования:</p><h3>Что такое нормализация и денормализация?</h3><p>Нормализация отношений в SQL призвана <a href="https://tproger.ru/translations/db-scheme-design-guide/">организовать информацию в базе данных</a> таким образом, чтобы она не занимала много места и с ней было удобно работать. Это удаление избыточных данных, устранение дублей, идентификация наборов связанных данных через PRIMARY KEY, etc.Соответственно, денормализация является обратным процессом, который вносит в нормализованную таблицу избыточные данные.Подробнее о пяти нормальных формах и форме Бойса-Кодда можно узнать <a href="https://www.youtube.com/watch?v=nsXV4PGMmrk&amp;list=PLtULzFUr0kI5YKdBKKAzt7AFjjoMnGX_a">из данного видеокурса</a>.</p><h3>Объясните разницу между командами DELETE и TRUNCATE”</h3><p>Команда DELETE — это DML-операция, которая удаляет записи из таблицы, соответствующие заданному условию:</p><p>При этом создаются логи удаления, то есть операцию можно отменить.А вот команда TRUNCATE — это DDL-операция, которая полностью пересоздаёт таблицу, и отменить такое удаление невозможно:</p><h3>Чем VARCHAR отличается от NVARCHAR?</h3><p>Главное отличие в том, что VARCHAR хранит значения в формате ASCII, где символ занимает один байт, а NVARCHAR хранит значения в формате Unicode, где символ «весит» 2 байта. Тип VARCHAR следует использовать, если вы уверены, что в значениях не будет Unicode-символов. Например, VARCHAR можно применить к адресам электронной почты, состоящих из ASCII-символов.</p><h2>Практика</h2><h3>Как выбрать записи с нечётными Id?</h3><p>Один из самых распространённых вопросов на собеседовании. SQL запрос для выбора записей с нечётными id должен выглядеть следующим образом:</p><p>Если остаток от деления id на 2 равен нулю, перед нами чётное значение, и наоборот.</p><h3>Как найти дубли в поле email?</h3><p>Функция COUNT() возвращает количество строк из поля email. Оператор HAVING работает почти так же, как и WHERE, вот только применяется не для всех столбцов, а для набора, созданного оператором GROUP BY.</p><h3>При выборке из таблицы прибавьте к дате 1 день</h3><p>Функция DATE_ADD() прибавляет к дате заданный промежуток времени. Синтаксис выглядит следующим образом:</p><h3>Выберите только уникальные имена</h3><p>SELECT DISTINCT возвращает разные значения, даже если в выбранном столбце есть дубли.</p><h3>Найдите в таблице среднюю зарплату работников</h3><p>Функция AVG() применяется только к числовым типам данных и возвращает среднее значение по столбцу.</p><h3>А теперь получите список сотрудников с зарплатой выше средней</h3><h3>Даны таблицы workers и departments. Найдите все департаменты без единого сотрудника</h3><h3>Замените в таблице зарплату работника на 1000, если она равна 900, и на 1500 в остальных случаях</h3><p>Замена значений — одна из наиболее часто встречаемых задач по SQL на собеседованиях. Решить её несложно:</p><p>Оператор UPDATE используется для изменения существующих записей. Но ответы на подобные вопросы с собеседований по SQL должны быть более развёрнутыми. Уточните,что после UPDATE следует указать, какие записи должны быть обновлены. В противном случае обновятся все записи в таблице.В нашем примере условие задаётся через оператор CASE: если текущая зарплата равна 900, изменяем её на 1000, в остальных случаях — на 1500.</p><h3>При выборке из таблицы пользователей создайте поле, которое будет включать в себя и имена, и зарплату</h3><p>Функция CONCAT() используется для конкатенации (объединения) строк, неявно преобразуя при этом любые типы данных в строки.</p><h3>Переименуйте таблицу</h3><p>С помощью оператора ALTER TABLE можно добавлять, удалять, изменять столбцы, а также изменять название таблицы.</p><h2>Часто задаваемые вопросы</h2><h3>Какие вопросы по SQL чаще всего задают на собеседованиях?</h3><p>Чаще всего спрашивают про типы JOIN, разницу между WHERE и HAVING, первичные и внешние ключи, нормализацию и подзапросы. Практические задания обычно включают поиск дублей, агрегатные функции и работу с датами.</p><h3>Достаточно ли знать только SELECT для собеседования по SQL?</h3><p>Нет. Помимо SELECT на собеседованиях проверяют знание DDL-команд (CREATE, ALTER, DROP), DML-операций (INSERT, UPDATE, DELETE), ограничений (PRIMARY KEY, FOREIGN KEY, UNIQUE) и умение работать с подзапросами.</p><h3>Как лучше всего готовиться к SQL-собеседованию?</h3><p>Разберите теорию (ключи, JOIN, нормализация), а затем решайте практические задачи на платформах вроде LeetCode, HackerRank или SQLBolt. Пишите запросы руками — простое чтение ответов не закрепляет навык. Для углублённого изучения рекомендуем материалы по <a href="https://tproger.ru/articles/osnovy-postgresql-dlya-nachinayushhih--ot-ustanovki-do-pervyh-zaprosov-250851">основам PostgreSQL</a>, <a href="https://tproger.ru/articles/sql-indeksy-za-10-minut">SQL-индексам</a> и <a href="https://tproger.ru/articles/sovety-po-optimizacii-sql-zaprosov-dlya-snizheniya-nagruzki-na-bd">оптимизации SQL-запросов</a>. Также полезно понимать, <a href="https://tproger.ru/experts/junior-middle-senior-developers-differences">какие навыки ожидают от разработчика на каждом грейде</a>. Оконные функции часто спрашивают — <a href="https://tproger.ru/translations/sql-window-functions">разбор с примерами</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Инструмент Managed Databases от DigitalOcean получил поддержку MySQL и Redis</title>
      <link>https://tproger.ru/news/managed-databases-mysql-redis</link>
      <comments>https://tproger.ru/news/managed-databases-mysql-redis?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Екатерина Никитина]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/managed-databases-mysql-redis</guid>
      <description><![CDATA[<p>Сервис DigitalOcean запускает кластер баз данных на MySQL, Redis или PostgreSQL за несколько минут: нужно выбрать движок, тариф и дата-центр.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/managed-databases-mysql-redis">Инструмент Managed Databases от DigitalOcean получил поддержку MySQL и Redis</a>»</p>]]></description>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 21 Aug 2019 14:34:24 GMT</pubDate>
      <content:encoded><![CDATA[<p>Команда DigitalOcean анонсировала Managed Databases для управления базами данных на MySQL и Redis. Управление базами на PostgreSQL доступно с февраля 2019 года.</p><p>Инструмент за несколько минут запускает кластер баз данных на любом из трёх движков. Нужно только выбрать движок, тарифный план в зависимости от потребностей проекта и дата-центр. Если потребности изменятся, можно будет изменить и тарифный план.</p><p>Managed Databases сам ежедневно делает бэкапы, они хранятся по семь дней. Безопасность передачи данных обеспечивает оконечное шифрование. Все базы работают в пределах приватной сети. Можно даже полностью запретить запросы к ним из публичной части Интернета, а разрешить — лишь для нескольких источников из «белого списка».</p><p>Инструмент поддерживает MySQL версии 8, Redis версии 5 и PostgreSQL версий 10 и 11.</p>]]></content:encoded>
    </item>
    <item>
      <title>Устраняем типичные ошибки в MySQL</title>
      <link>https://tproger.ru/translations/troubleshoot-common-errors-in-mysql</link>
      <comments>https://tproger.ru/translations/troubleshoot-common-errors-in-mysql?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Klara Oswald]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/troubleshoot-common-errors-in-mysql</guid>
      <description><![CDATA[<p>Статья расскажет, как определять проблемы и ошибки на сервере баз данных MySQL. Вы научитесь определять причины проблем и устранять их.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/troubleshoot-common-errors-in-mysql">Устраняем типичные ошибки в MySQL</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 24 May 2019 06:28:43 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://ru.wikipedia.org/wiki/MySQL">MySQL</a> — система управления базами данных (<a href="https://ru.wikipedia.org/wiki/Система_управления_базами_данных">СУБД</a>) с открытым исходным кодом от компании <a href="https://ru.wikipedia.org/wiki/Oracle">Oracle</a>. Она была разработана и оптимизирована специально для работы веб-приложений. MySQL является неотъемлемой частью таких веб-сервисов, как Facebook, Twitter, Wikipedia, YouTube и многих других.</p><p>Эта статья расскажет, как определять, с чем связаны частые ошибки на сервере MySQL, и устранять их. Эта статья — часть нашего <a href="https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij">полного путеводителя по SQL</a>.</p><h2>Не удаётся подключиться к локальному серверу</h2><p>Одной из распространённых ошибок подключения клиента к серверу является «ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)».</p><figure><img src="https://media.tproger.ru/uploads/2019/05/cant-connect-to-local-mysql-db-server.png" alt="" /></figure><p>Эта ошибка означает, что на хосте не запущен сервер MySQL (mysqld) или вы указали неправильное имя файла сокета Unix или порт TCP/IP при попытке подключения.</p><p>Убедитесь, что сервер работает. Проверьте процесс с именем mysqld на хосте сервера, используя команды <a href="https://ru.wikipedia.org/wiki/Ps">ps</a> или <a href="http://lumpics.ru/linux-grep-command-examples/">grep</a>, как показано ниже.</p><p>Если эти команды не показывают выходных данных, то сервер БД не работает. Поэтому клиент не может подключиться к нему. Чтобы запустить сервер, выполните команду <a href="https://losst.ru/upravlenie-sluzhbami-linux#_systemctl">systemctl</a>.</p><p>Чтобы проверить состояние службы MySQL, используйте следующую команду:</p><figure><img src="https://media.tproger.ru/uploads/2019/05/check-mysql-status.png" alt="" /></figure><p>Если в результате выполнения команды произошла ошибка службы MySQL, вы можете попробовать перезапустить службу и ещё раз проверить её состояние.</p><figure><img src="https://media.tproger.ru/uploads/2019/05/restart-mysql-service.png" alt="" /></figure><p>Если сервер работает (как показано) и вы по-прежнему видите эту ошибку, вам следует проверить, не заблокирован ли порт TCP/IP брандмауэром или любой другой службой блокировки портов.</p><p>Для поиска порта, который прослушивается сервером, используйте команду netstat.</p><h2>Не удаётся подключиться к серверу MySQL</h2><p>Ещё одна похожая и часто встречающаяся ошибка подключения — «(2003) Can’t connect to MySQL server on ‘server’ (10061)». Это означает, что в сетевом соединении было отказано.</p><p>Следует проверить, работает ли в системе сервер MySQL (смотрите выше) и на тот ли порт вы подключаетесь (как найти порт, можно посмотреть выше).</p><p>Похожие частые ошибки, с которыми вы можете столкнуться при попытке подключиться к серверу MySQL:</p><h2>Ошибки запрета доступа в MySQL</h2><p>В MySQL учётная запись (УЗ) определяется именем пользователя и клиентским хостом, с которого пользователь может подключиться. УЗ может также иметь данные для аутентификации (например, пароль).</p><p>Причин для запрета доступа может быть много. Одна из них связана с учётными записями MySQL, которые сервер разрешает использовать клиентским программам при подключении. Это означает, что имя пользователя, указанное в соединении, может не иметь прав доступа к базе данных.</p><p>В MySQL есть возможность создавать учётные записи, позволяющие пользователям клиентских программ подключаться к серверу и получать доступ к данным. Поэтому при ошибке доступа проверьте разрешение УЗ на подключение к серверу через клиентскую программу.</p><p>Увидеть разрешённые привилегии учётной записи можно, выполнив в консоли команду SHOW GRANTS<br />Входим в консоль (пример для Unix, для Windows консоль можно найти в стартовом меню):<br /></p><p>В консоли вводим команду:</p><p>Дать привилегии конкретному пользователю в БД по IP-адресу можно, используя следующие команды:</p><p>Ошибки запрещённого доступа могут также возникнуть из-за проблем с подключением к MySQL (см. выше).</p><h2>Потеря соединения с сервером MySQL</h2><p>С этой ошибкой можно столкнуться по одной из следующих причин:</p><ul><li>плохое сетевое соединение;</li><li>истекло время ожидания соединения;</li><li>размер <a href="https://ru.wikipedia.org/wiki/BLOB">BLOB </a> больше, чем max_allowed_packet.</li></ul><p>В первом случае убедитесь, что у вас стабильное сетевое подключение (особенно, если подключаетесь удалённо).</p><p>Если проблема с тайм-аутом соединения (особенно при первоначальном соединении MySQL с сервером), увеличьте значение параметра connect_timeout.</p><p>В случае с размером BLOB нужно установить более высокое значение для max_allowed_packet в файле конфигурации /etc/my.cnf в разделах [mysqld] или [client] как показано ниже.</p><p>Если файл конфигурации недоступен, это значение можно установить с помощью следующей команды.</p><h2>Слишком много подключений</h2><p>Эта ошибка означает, что все доступные соединения используются клиентскими программами. Количество соединений (по умолчанию 151) контролируется системной переменной max_connections. Устранить проблему можно, увеличив значение переменной в файле конфигурации /etc/my.cnf.</p><h2>Недостаточно памяти</h2><p>Если такая ошибка возникла, это может означать, что в MySQL недостаточно памяти для хранения всего результата запроса.</p><p>Сначала нужно убедиться, что запрос правильный. Если это так, то нужно выполнить одно из следующих действий:</p><ul><li>если клиент MySQL используется напрямую, запустите его с ключом --quick switch, чтобы отключить кешированные результаты;</li><li>если вы используете драйвер MyODBC, пользовательский интерфейс (UI) имеет расширенную вкладку с опциями. Отметьте галочкой «Do not cache result» (не кешировать результат).</li></ul><p>Также может помочь MySQL Tuner. Это полезный скрипт, который подключается к работающему серверу MySQL и даёт рекомендации по настройке для более высокой производительности.</p><h2>MySQL продолжает «падать»</h2><p>Если такая проблема возникает, необходимо выяснить, заключается она в сервере или в клиенте. Обратите внимание, что многие сбои сервера вызваны повреждёнными файлами данных или индексными файлами.</p><p>Вы можете проверить состояние сервера, чтобы определить, как долго он работал.</p><p>Чтобы узнать время безотказной работы сервера, запустите команду mysqladmin.</p><figure><img src="https://media.tproger.ru/uploads/2019/05/Find-MySQL-Server-Uptime.png" alt="" /></figure><p>Кроме того, можно остановить сервер, сделать отладку MySQL и снова запустить службу. Для отображения статистики процессов MySQL во время выполнения других процессов откройте окно командной строки и введите следующее:</p><p>Или</p><h2>Заключение</h2><p>Самое важное при диагностике — понять, что именно вызвало ошибку. Следующие шаги помогут вам в этом: Не уверены в выборе СУБД? <a href="https://tproger.ru/translations/sqlite-mysql-postgresql-comparison">Сравнение трёх популярных</a>.</p><ul><li>Первый и самый важный шаг — просмотреть журналы MySQL, которые хранятся в каталоге /var/log/mysql/. Вы можете использовать утилиты командной строки вроде tail для чтения файлов журнала.</li><li>Если служба MySQL не запускается, проверьте её состояние с помощью systemctl. Или используйте команду journalctl (с флагом -xe) в systemd.</li><li>Вы также можете проверить файл системного журнала (например, /var/log/messages) на предмет обнаружения ошибок.</li><li>Попробуйте использовать такие инструменты, как <a href="https://www.8host.com/blog/monitoring-proizvoditelnosti-mysql-pri-pomoshhi-mytop/">Mytop</a>, <a href="https://linux-notes.org/glances-sistema-monitoringa-v-rezhime-real-nogo-vremeni-dlya-linux/">glances</a>, <a href="https://ru.wikipedia.org/wiki/Top">top</a>, <a href="https://ru.wikipedia.org/wiki/Ps">ps</a> или <a href="https://ru.wikipedia.org/wiki/Htop">htop</a>, чтобы проверить, какая программа использует весь ресурс процессора или блокирует машину. Они также помогут определить нехватку памяти, дискового пространства, файловых дескрипторов или какого-либо другого важного ресурса.</li><li>Если проблема в каком-либо процессе, можно попытаться его принудительно остановить, а затем запустить (при необходимости).</li><li>Если вы уверены, что проблемы именно на стороне сервера, можете выполнить команды: mysqladmin -u root ping или mysqladmin -u root processlist, чтобы получить от него ответ.</li><li>Если при подключении проблема не связана с сервером, проверьте, нормально ли работает клиент. Попробуйте получить какие-либо его выходные данные для устранения неполадок.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Представлен стабильный релиз MySQL 8.0</title>
      <link>https://tproger.ru/news/mysql-8-0-generally-available</link>
      <comments>https://tproger.ru/news/mysql-8-0-generally-available?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Светлана Хачатурян]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/mysql-8-0-generally-available</guid>
      <description><![CDATA[<p>Стабильная MySQL 8.0 получила поддержку NoSQL и ГИС, расширенные функции JSON, регулярных выражений и улучшения безопасности и надёжности.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/mysql-8-0-generally-available">Представлен стабильный релиз MySQL 8.0</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 20 Apr 2018 17:14:30 GMT</pubDate>
      <content:encoded><![CDATA[<p>Спустя почти 7 месяцев с момента <a href="https://tproger.ru/news/mysql-8-0-rc1/">выхода</a> первого «сырого» варианта MySQL 8.0, Oracle <a href="https://blogs.oracle.com/mysql/announcing-general-availability-of-mysql-80">презентовала</a> официальную стабильную версию популярной реляционной СУБД. Помимо ранее реализованных опций, в обновлении представлена поддержка NoSQL и ГИС, улучшены функции по работе с таблицами и обработке регулярных выражений, а также повышены показатели безопасности, доступности, управляемости и надёжности.</p><h3>Что нового?</h3><p>Система управления базами данных MySQL 8.0 оснащена:</p><ul><li>поддержкой Emoji;</li><li>MySQL Document Store, упраздняющей необходимость в создании отдельной NoSQL-таблицы для смешанных приложений:</li></ul><figure><img src="https://media.tproger.ru/uploads/2018/04/mysql8documentstorearchitecture.png" alt="" /></figure><ul><li>оконными функциями SQL;</li><li>поддержкой рекурсивных и нерекурсивных Common Table Expressions (CTE), позволяющими использовать временные именованные результирующие наборы, задаваемые при помощи оператора WITH:</li></ul><figure><img src="https://media.tproger.ru/uploads/2018/04/mysql8cteandwindowsfeatures.jpg" alt="" /></figure><ul><li>поддержкой NOWAIT и SKIP LOCKED, которые можно использовать для управления поведением при наличии блокировок в момент выполнения выражений SELECT ... FOR SHARE и SELECT ... FOR UPDATE;</li><li>поддержкой нисходящих индексов;</li><li>функцией GROUPING(), отделяющей полученные после агрегирования строк при GROUP BY с использованием ROLLUP значения NULL от NULL в обычных сгруппированных строках.</li></ul><h3>JSON</h3><p>Особо выделяются нововведения, реализованные в рамках работы с форматом JSON:</p><ul><li>расширенный синтаксис для задания диапазонов (например, SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]'); в качестве результата выдаст [2, 3, 4]);</li><li>табличные функции JSON для манипулирования данными этого формата напрямую через SQL;</li><li>функции агрегирования JSON_ARRAYAGG() для генерации JSON-массивов и JSON_OBJECTAGG() для генерации JSON-объектов;</li><li>функции слияния JSON, позволяющие удалять дубликаты в пользу второго документа (например,JSON_MERGE('{"a":1,"b":2 }','{"a":3,"c":4 }'); вернёт {"a":3,"b":2,"c":4}.</li><li>улучшенная сортировка с помощью переменных сортировочных ключей, решающая задачу до 18 раз быстрее предыдущей версии инструмента.</li></ul><p>Отмечается, что MySQL 8.0 работает до 2 раз быстрее MySQL 5.7.</p><figure><img src="https://media.tproger.ru/uploads/2018/04/performance_80.png" alt="" /></figure><p>Более подробно с техническими деталями обновлённой СУБД можно ознакомиться в официальной <a href="https://dev.mysql.com/doc/refman/8.0/en/">документации</a>. MySQL 8.0 <a href="https://dev.mysql.com/downloads/mysql/">доступна</a> для скачивания на Windows, macOS и популярные дистрибутивы Linux.</p>]]></content:encoded>
    </item>
    <item>
      <title>Amazon анонсировала бессерверный сервис баз данных</title>
      <link>https://tproger.ru/news/amazon-aurora-serverless</link>
      <comments>https://tproger.ru/news/amazon-aurora-serverless?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вячеслав Шарунов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/amazon-aurora-serverless</guid>
      <description><![CDATA[<p>Aurora Serverless отделяет хранилище данных от обработки, автоматически масштабируется и тарифицирует процессоры и память посекундно при работе базы.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/amazon-aurora-serverless">Amazon анонсировала бессерверный сервис баз данных</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Amazon]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 03 Dec 2017 15:39:53 GMT</pubDate>
      <content:encoded><![CDATA[<p>На прошедешей конференции <a href="https://reinvent.awsevents.com/">AWS re:Invent</a> компания Amazon <a href="https://aws.amazon.com/blogs/aws/in-the-works-amazon-aurora-serverless/">анонсировала</a> выпуск нового сервиса баз данных, упрощающей работу с реляционными БД. Сервис построена поверх существующей системы <a href="https://aws.amazon.com/rds/aurora/">Amazon Aurora</a> и не требует непрерывной обработки данных.</p><h3>Бессерверная Aurora</h3><p>Особенность новой системы <a href="https://aws.amazon.com/rds/aurora/serverless/">Amazon Aurora Serverless</a> состоит в том, что хранилище данных отделено от процесса их обработки. Пользователи этого сервиса платят только за обработку данных, когда база данных реально занята какой-то работой. Разумеется, оплату за хранение данных никто не отменял, но стоит это относительно дёшево.</p><p>Aurora Serverless предлагает пользователям автоматическое масштабирование по требованию. Заказчикам не придётся заниматься резервированием экземпляров базы данных. Они платят только за использованные ресурсы процессоров и памяти с посекундной тарификацией. Перевод существующих баз данных на бессерверную версию Aurora, по словам Amazon, происходит без каких-либо усилий. <a href="https://media.tproger.ru/uploads/2017/12/aurora_serverless_arch_1.png"></a></p><h3>Когда можно пользоваться?</h3><p>Amazon Web Services планирует перевести Aurora Serverless из демонстрационного в рабочий режим за два этапа: в первой половине 2018 года — с функциональностью MySQL, и до конца будущего года — PostgreSQL. Получить же доступ к превью-версии можно уже сегодня. Достаточно подать заявку <a href="https://pages.awscloud.com/amazon-aurora-serverless-preview.html">на сайте</a> AWS.</p><h3>Другие анонсы от Amazon</h3><p>Отметим также, что на re:Invent компания Amazon <a href="https://tproger.ru/news/new-service-amazon-translate/">представила</a> сервис для перевода в режиме реального времени Translate и <a href="https://tproger.ru/news/aws-i3metal-instance/">сообщила</a> о запуске инстансов i3.metal с прямым доступом к «железу». Помимо этого, было <a href="https://tproger.ru/news/amazon-ml-solutions-lab-and-rekognition-features/">анонсировано</a>, что компания предоставит клиентам AWS доступ к своим внутренним системам машинного обучения.</p>]]></content:encoded>
    </item>
    <item>
      <title>Представлен первый релиз-кандидат MySQL 8.0</title>
      <link>https://tproger.ru/news/mysql-8-0-rc1</link>
      <comments>https://tproger.ru/news/mysql-8-0-rc1?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вячеслав Шарунов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/mysql-8-0-rc1</guid>
      <description><![CDATA[<p>Первый релиз-кандидат MySQL 8.0 меняет кодировку по умолчанию на utf8mb4 и добавляет оконные функции и рекурсивные табличные выражения.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/mysql-8-0-rc1">Представлен первый релиз-кандидат MySQL 8.0</a>»</p>]]></description>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Unicode]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 28 Sep 2017 19:28:32 GMT</pubDate>
      <content:encoded><![CDATA[<p>MySQL перескакивает несколько версий в своей нумерации (на данный момент стабильная версия имеет номер 5.7). Это связано с тем, что версия с нумерацией 6.0 отменена, а 7.0 зарезервирована для кластерной версии продукта.</p><h3>Функции, включённые в MySQL 8.0</h3><ul><li>Поддержка Unicode 9.0 из коробки;</li><li><a href="http://mysqlserverteam.com/mysql-8-0-2-introducing-window-functions/">Оконные функции</a> и рекурсивный синтаксис SQL для запросов, которые ранее были невозможны или трудны для написания;</li><li>Расширенная нативная поддержка данных из JSON-файлов и функциональности документоориентированных систем.</li></ul><h3>Поддержка Unicode 9.0</h3><p>MySQL 8.0 больше не поддерживает latin1 в качестве кодировки по умолчанию. Рекомендуемым набором символов в новой версии является utf8mb4, который быстрее устаревшего utf8mb3 и поддерживает более гибкие правила сравнения символов. utf8mb4 также чувствителен к регистру.</p><h3>Оконные функции</h3><p>Многие другие реализации языка SQL поддерживают оконные функции — способ выполнить вычисления одновременно по нескольким строкам, сохраняя при этом доступ к каждой из строк отдельно. Похожее можно было сделать в MySQL и без оконных функций, однако более медленным и громоздким способом. MySQL 8.0 добавляет оконные функции c использованием ключевого слова OVER, которые по своей сущности похожи на уже используемые в PostgreSQL.</p><p>Ещё одной особенностью нового релиза являются рекурсивные табличные выражения, позволяющие выполнять рекурсивные операции как часть запроса, не прибегая к использованию курсора или других более медленных методов.</p><h3>JSON-файлы и документоориентированные базы</h3><p>В версии 5.7 уже появилась поддержка JSON-файлов, что делает MySQL конкурентноспособной с базами NoSQL, использующими JSON по умолчанию. Версия 8.0 расширяет поддержку JSON, добавляя новые функции агрегации, позволяющие объединить данные структурированных баз MySQL и документоориентированных NoSQL в один запрос.</p><p>Ещё одним улучшением, связанным с JSON, является появившаяся возможность MySQL хранить данные в документоориентированных базах. Чтение и запись из таких хранилищ являются транзакционно последовательными, что позволяет выполнять откаты данных JSON при необходимости. Географические данные, хранимые в формате GeoJSON, могут быть проиндексированы, что позволяет производить поиск по близости координат.</p><h3>Другие ключевые функции MySQL 8.0</h3><ul><li>Дополнительные параметры обработки заблокированных строк при помощи ключевых слов SKIP LOCKED и NOWAIT. SKIP LOCKED позволяет пропускать заблокированные строки во время операций, NOWAIT выдаст ошибку доступа при встрече заблокированной строки;</li><li>MySQL автоматически масштабируется до объёма доступной памяти, чтобы наилучшим образом использовать виртуальные машины;</li><li>Индексы можно вручную исключить из оптимизатора запросов при помощи функции «невидимый индекс». Индексы, отмеченные как невидимые, постоянно обновляются с изменениями в таблицах, но не используются для оптимизации запросов.</li></ul><h3>Ожидаемая дата релиза</h3><p>MySQL до сих пор не анонсировала точную дату выхода общедоступной версии 8.0, но поскольку политика компании придерживается правила «новая общедоступная версия каждые 18–24 месяца», то стоит ожидать релиз в октябре 2017 года. Напомним, что версия 5.7 стала доступна в октябре 2015 года.</p><h3>Установка</h3><p>Скачать и установить новую версию для разработчиков можно <a href="https://dev.mysql.com/downloads/mysql/">с официальной страницы</a> продукта.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как при помощи Node.js + MySQL упорядочить 100 Гбайт данных</title>
      <link>https://tproger.ru/articles/nodejs-and-mysql</link>
      <comments>https://tproger.ru/articles/nodejs-and-mysql?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ярослав Сарницкий]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/nodejs-and-mysql</guid>
      <description><![CDATA[<p>Связка Node.js и MySQL помогает работать с миллиардами строк и сотнями гигабайт данных; выбор базы зависит от индексов, схемы и требований ACID.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/nodejs-and-mysql">Как при помощи Node.js + MySQL упорядочить 100 Гбайт данных</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 26 Jul 2017 17:18:47 GMT</pubDate>
      <content:encoded><![CDATA[<p>Эта статья поведает о том, как можно эффективно обрабатывать миллиарды строк, которые занимают сотни гигабайт памяти, при помощи Node.js и MySQL. Вторичная цель статьи — это помочь определиться, подходит ли такое решение для ваших нужд. Код, который будет использоваться в этом примере, можно найти на <a href="https://github.com/RisingStack/mysql-large-data-handling">GitHub</a>.</p><h2>Почему Node.js и MySQL?</h2><p>MySQL будет использоваться для хранения информации из <a href="https://trace.risingstack.com/">Trace</a> — инструмента Node.js для отладки и мониторинга производительности.</p><p>Выбор пал на MySQL, потому что на момент принятия решения Postgres не очень хорошо обновлял строки и обновление неизменяемых данных было бы неоправданно сложным. К сожалению, эти решения не соответствуют требованиям <a href="https://ru.wikipedia.org/wiki/ACID">ACID</a>, что затрудняет их использование.</p><p>Однако при  хорошем индексировании и правильном планировании MySQL, это может быть подходящим решением для поставленной задачи.</p><p>MySQL имеет несколько модулей хранения. InnoDB является стандартным, в котором есть большинство функций. Однако следует учитывать, что таблицы InnoDB не изменяемы, что означает, что каждый оператор ALTER TABLE скопирует все данные в новую таблицу. Это ухудшит ситуацию, когда возникнет необходимость в переносе уже существующей базы данных.</p><p>Если имеются номинальные значения, каждое из которых имеет множество связанных данных, например, у каждого из пользователей есть множество продуктов, а пользователей довольно много — пожалуй, наиболее оптимальным будет создание отдельных таблиц с именем  &lt;user_id&gt;_&lt;entity_name&gt; для каждой из сущностей. Таким образом можно значительно уменьшить размер конкретной таблицы.</p><p>Кроме того, если не разделить пользователей по таблицам, очистка данных пользователя в случае удаления учетной записи будет являться операцией с постоянной временной сложностью алгоритма O(1), когда время выполнения не зависит от размера обрабатываемых данных. Это очень важно, потому что, если нужно удалить большое количество значений из больших таблиц, MySQL может решить использовать неверный индекс или вообще не использовать индексы. Если не создавать отдельных таблиц для каждой сущности, вы не сможете использовать <a href="https://dev.mysql.com/doc/refman/5.7/en/index-hints.html">подсказки</a> для DELETE, чтобы указать MySQL, какие именно индексы нужно обрабатывать. Вы также можете захотеть использовать ALTER для таблицы, чтобы удалить данные, но это приведет к копированию каждой строки в новую таблицу, что не является рациональным при использовании одной большой таблицы для всех пользователей.</p><p>Создание таблиц для каждого пользователя, на первый взгляд, усложняет задачу, но это может быть единственным решением, когда дело касается удаления пользователей или подобных объектов с огромным количеством связанных данных.</p><p>Однако перед тем как использовать динамически созданные таблицы, стоит попробовать удалить строки в чанках (англ.  chunks). Такой вариант также может сработать и в этом случае упростит весь процесс. Конечно, если данные появляются быстрее, чем происходит их удаление, решение с чанками не подойдет.</p><p>Но что если таблицы все еще остались огромными даже после их разделения по пользователями и также нужно удалить устаревшие строки? А данные все еще появляются быстрее, чем происходит их удаление? В этом случае стоит попробовать встроенный в MySQL инструмент для секционирования таблиц. Это удобно, когда нужно разделить данные по постоянным или переменным значениям, например, по времени создания.</p><h2>Секционирование таблиц с помощью MySQL</h2><p>С MySQL секционированная таблица будет работать так, как если бы она была несколькими таблицами, но можно использовать тот же привычный интерфейс без изменений в логике приложения. Это также означает, что можно удалять разделы, как если бы происходило удаление таблиц.</p><p><a href="https://dev.mysql.com/doc/refman/5.7/en/partitioning-management.html">Документация</a> хорошая, но довольно многословная (в конце концов, это не простая тема), поэтому просто создадим секционированную таблицу.</p><p>В коде нет ничего необычного до PARTITION BY RANGE.</p><p>В MySQL таблицы можно разделить на RANGE, LIST, COLUMN, HASH и KEY, о которых можно прочитать в документации. Стоит обратить внимание, что ключ секционирования должен быть частью первичного ключа или любых уникальных индексов.</p><p>Все, что начинается с &lt;date&gt;, должно быть понятным. Каждый раздел содержит значения, для которых столбец created_at меньше даты следующего дня. Это также означает, что from20120414 содержит все данные, которые старше 2012-04-15, так что этот раздел будет удален при выполнении очистки.</p><p>Разделы start и future нуждаются в некотором разъяснении: future содержит данные для дат, которые еще не включены в правила секционирования. Если невозможно выполнить секционирование вовремя, все данные, поступившие 2017-05-17 и позже, будут в этом разделе, и мы ничего не потеряем. Раздел start является неким защитным механизмом. Ожидается, что все строки имеют значение DATETIME created_at, однако нужно подготовиться к возможным ошибкам. Если по какой-то причине в строке в этом поле будет NULL, она окажется в разделеstart. Это укажет нам на ошибки, и, значит, нужно разбираться.</p><p>При использовании секционирования MySQL сохранит эти данные на отдельных частях диска, как если бы они были отдельными таблицами, и автоматически упорядочит все данные на основании ключа секционирования.</p><p>Однако есть некоторые ограничения при использовании секционирования, которые необходимо принять во внимание:</p><ul><li>кэш запросов не поддерживается;</li><li>внешние ключи не поддерживаются для секционированных таблиц InnoDB;</li><li>секционированные таблицы не поддерживают индексы или поисковые запросы FULLTEXT.</li></ul><p>Ограничений <a href="https://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations.html">гораздо больше</a>, это лишь основные.</p><p>Если нужно создать новый раздел, то необходимо реорганизовать существующий и разбить его в соответствии с потребностями:</p><p>Удаление разделов происходит с помощью ALTER TABLE, поскольку выполняется аналогично удалению таблиц:</p><p>Как можно увидеть, нужно включать фактические имена и описания разделов в операторах.  Они не могут быть динамически генерированы MySQL, поэтому придется обрабатывать их в логике приложения. Это будет рассмотрено дальше.</p><h2>Пример секционирования при помощи Node.js и MySQL</h2><p>Рассмотрим практическое решение. Для примера здесь используется <a href="https://www.google.com.ua/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;cad=rja&amp;uact=8&amp;ved=0ahUKEwjD9tnyqKXVAhXjO5oKHbe5A74QFgglMAA&amp;url=http%3A%2F%2Fknexjs.org%2F&amp;usg=AFQjCNEr2553-KxK7eWywsTUvohfV8mBdA">knex</a> — инструмент запросов для JavaScript. Для тех, кто знаком с SQL, понимание кода не составит труда.</p><p>Сначала создадим таблицу:</p><p>Это практически то же выражение, что было выше, но в задаче необходимо динамически создавать имена и описания разделов. Вот почему был создан метод getPartitionStrings.</p><p>Первая строка:</p><p>MAX_DATA_RETENTION - 2 = 5 создает последовательность от 5 до -2 (последнее число не входит в последовательность) → [ 5, 4, 3, 2, 1, 0, -1 ], после этого вычитаются  значения из текущего времени и создается раздел today и его предел tomorrow. Порядок очень важен, поскольку MySQL выдаст ошибку, если значения для разделения находятся не в возрастающем порядке.</p><h2>Пример удаления больших масштабов данных при помощи MySQL и Node.js</h2><p>Теперь можно шаг за шагом разобраться с удалением данных. Полный код можно посмотреть <a href="https://github.com/RisingStack/mysql-large-data-handling/blob/master/src/partitioning.js#L75">здесь</a>.</p><p>Первый метод, removeExpired, получает список текущих разделов, затем передает его в repartition.</p><p>Сначала выбираются все существующие в настоящее время разделы из таблицы information_schema.partitions, которая управляется MySQL.</p><p>Затем создаются все разделы, которые должны существовать для таблицы. Если A — это множество разделов, которые существуют, а B — множество разделов, которые должны существовать, тогда:</p><p>partitionsToBeCreated = B \ A</p><p>partitionsToBeDropped = A \ B</p><p>getPartitionsThatShouldExist creates set B.</p><p>Создание объектов разделов очень похоже на создание выражения CREATE TABLE ... PARTITION BY RANGE. Также важно проверить, является ли раздел, который будет создан, старше текущего самого старого раздела, ведь со временем может понадобиться изменить dataRetention.</p><p>Пример одного из возможных сценариев:</p><blockquote>Пользователи могут хранить данные в течение 7 дней, но также существует возможность расширить этот диапазон до 10 дней. Сначала у пользователя есть разделы, которые охватывают дни в следующем порядке: [ start, -7, -6, -5, -4, -3, -2, -1, future ]. Вскоре пользователь решает увеличить срок хранения данных. Отсутствующие разделы в этом случае: [ -10, -9, -8, 0 ].При очистке текущий скрипт попытается реорганизовать раздел future для отсутствующих разделов, добавляя их после текущих.Создание дополнительных разделов, которые старше 7 дней, не имеет смысла, потому что эти данные будут заброшены так далеко, что это создаст список разделов, который выглядит так: [ start, -7, -6, -5, -4, -3, -2, -1, -10, -9, -8, 0, future ]. Непоследовательно возрастающий список приведет к ошибке MySQL, и вся операция завершится неудачей.</blockquote><p>Функция MySQL TO_DAYS(date) вычисляет количество дней, прошедших с 1 января 2000 года, поэтому мы повторяем это в JavaScript.</p><p>Теперь, когда созданы разделы, которые нужно удалить, и разделы, которые должны быть созданы, нужно создать новый раздел для нового дня.</p><p>Здесь просто выполняется код для создания новых разделов.</p><p>Запуская этот скрипт ежечасно, можно убедиться в том, что все идет по плану. Это также поможет выполнять очистку должным образом, по крайней мере, один раз в день.</p><p>Итак, первое, что нужно проверить — это создать любой раздел. Это должно произойти только при первом прогоне, после чего функция 23 раза в день будет лишь выполнять проверку.</p><p>Также необходимо удалить устаревшие разделы.</p><p>Этот код создает тот же самый ALTER TABLE ... DROP PARTITION, который был показан выше.</p><p>И, наконец, все готово к реорганизации.</p><h2>Заключение</h2><p>Как можно видеть, вопреки распространенному мнению, совместимые с ACID решения СУБД, такие как MySQL, могут использоваться, когда обрабатываются большие объемы данных, поэтому необязательно отказываться от функций транзакционных баз данных.</p><p>Тем не менее, разделение таблиц имеет довольно много ограничений, а это означает, что невозможно будет использовать все возможности, которые InnoDB предоставляет для обеспечения гарантированного сохранения данных. Также может потребоваться обработать в логике приложения то, что без секционирования было бы реализовано средствами СУБД. Например, ограничения внешнего ключа или полнотекстовый поиск.</p>]]></content:encoded>
    </item>
    <item>
      <title>Курс «Изучение программирования. SQL»</title>
      <link>https://tproger.ru/video/sql-introduction</link>
      <comments>https://tproger.ru/video/sql-introduction?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Лапа]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/video/sql-introduction</guid>
      <description><![CDATA[<p>Курс знакомит с SQL и реляционными базами данных: от составления запросов и нормализации до изучения нормальных форм и языка управления данными.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/video/sql-introduction">Курс «Изучение программирования. SQL»</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Обучающие курсы]]></category>
      <category><![CDATA[Видео]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 03 May 2017 18:45:25 GMT</pubDate>
      <content:encoded><![CDATA[<p>SQL — язык манипулирования и управления реляционными базами данных — хранилищами всевозможных данных: от простых Email-ов и логинов пользователей до построения сложных высоконагруженных схем. Обо всем этом и о многом другом — в этом курсе от Радько Петра (CMTV), записанном в 2014 году.</p><p>В ходе изучения курса вы узнаете, что такое реляционная база данных, как составлять запросы, что такое нормализация базы данных, какие бывают нормальные формы и еще немного о тонкостях языка SQL.</p><p>Советуем также прочитать <a href="https://tproger.ru/articles/avoid-mistakes-with-mysql/">нашу статью</a> о том, как избегать ошибок при работе с MySQL.</p>]]></content:encoded>
    </item>
    <item>
      <title>Настал черед MySQL: неизвестная группа хакеров вымогает деньги за восстановление удаленных данных с сотен MySQL-серверов</title>
      <link>https://tproger.ru/news/mysql-dump</link>
      <comments>https://tproger.ru/news/mysql-dump?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Антон]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/mysql-dump</guid>
      <description><![CDATA[<p>Злоумышленники копируют и удаляют базы, требуя 0,2 биткоина за возврат; по данным GuardiCore, доступные из Сети серверы взламывают перебором паролей.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/mysql-dump">Настал черед MySQL: неизвестная группа хакеров вымогает деньги за восстановление удаленных данных с сотен MySQL-серверов</a>»</p>]]></description>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 25 Feb 2017 13:17:15 GMT</pubDate>
      <content:encoded><![CDATA[<p>Серия атак на серверы популярных СУБД продолжается. В этот раз, после MongoDB, ElasticSearch, Hadoop и CouchDB, хакерам успешно удалось атаковать сервера MySQL.</p><h3>В чем заключаются действия хакеров</h3><p>Суть атаки хакеров заключается в копировании данных с серверов жертв и их последующем удалении. За восстановление данных злоумышленники требуют оплату в размере 0,2 биткоина (<a href="https://www.calc.ru/kurs-BTC-RUB.html?text_quantity=0.2">около 13,5 тысяч рублей</a> на момент написания статьи). Согласно исследованию компании GuardiCore, для атаки применяется брутфорс (полный перебор паролей) MySQL-серверов, к которым можно получить доступ через Сеть. Сообщается, что иногда хакеры не делают предварительный дамп данных, поэтому жертва в общем случае не имеет никаких гарантий.</p><p>Для привлечения внимания жертвы хакеры обычно создают таблицу с названием WARNING в существующей схеме на сервере или создают новую схему с названием PLEASE_READ. Используется примерно следующий код:</p><p>Считается, что атаки начались 12 февраля на территории Нидерландов (IP 109.236.88.20) и продлились 30 часов, в течение которых хакерам удалось получить доступ к БД жертв. Использование хакерами различных тактик значительно усложняет поиск связей между атаками на сервера разных СУБД, однако их общая природа наталкивает на мысль, что действует одна и та же группа.</p><h3>Куда деньги на лечение скидывать?</h3><p>Для вымогания средств и приема платежей хакеры используют сайт в домене .onion. На момент написания статьи сайт все еще действует.</p><figure><img src="https://media.tproger.ru/uploads/2017/02/pic0-4.png" alt="" /></figure><p>Известно, что на указанные на этом сайте биткоин-счета уже поступило суммарно 10 платежей.</p><h3>Мораль</h3><p>Важный урок, который стоит извлечь из этой истории: первый шаг к безопасности — генерация устойчивого к брутфорсу пароля. Кстати, мы <a href="https://tproger.ru/digest/stop-using-simple-passwords/">рассказывали</a> о различных сервисах, с помощью которых можно удобно сгенерировать пароли.</p>]]></content:encoded>
    </item>
    <item>
      <title>Инструкция: как перевести проект Django с SQLite на MySQL без боли</title>
      <link>https://tproger.ru/articles/django-sqlite-to-mysql</link>
      <comments>https://tproger.ru/articles/django-sqlite-to-mysql?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Антон]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/django-sqlite-to-mysql</guid>
      <description><![CDATA[<p>Пошаговая инструкция миграции базы данных Django-проекта с SQLite3 на MySQL для конфигурации Ubuntu 16.04, Python 3.5.2 и Django 1.10.4.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/django-sqlite-to-mysql">Инструкция: как перевести проект Django с SQLite на MySQL без боли</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 03 Jan 2017 19:34:46 GMT</pubDate>
      <content:encoded><![CDATA[<p>SQLite3 является СУБД-движком по умолчанию в Python веб-фреймворке Django, а также, как <a href="https://sqlite.org/mostdeployed.html">сообщается</a> на официальном сайте проекта, самым часто используемым движком в мире. И он отлично походит для быстрого прототипирования веб-проекта, однако имеет ряд недостатков, о которых мы <a href="https://tproger.ru/translations/sqlite-mysql-postgresql-comparison/">рассказывали</a> в одной из статей на нашем сайте, и по мере роста веб-приложения приходится переходить на полнофункциональную РСУБД — например, MySQL. И здесь разработчик может столкнуться с проблемами. Мы предлагаем воспользоваться нижеследующей инструкцией, чтобы их избежать или хотя бы максимально снизить вероятность их появления.</p><p>Инструкция написана для следующей конфигурации: Ubuntu 16.04, Python 3.5.2, Django 1.10.4.</p><ol><li>Установка сервера и консольного клиента MySQL:$ sudo apt-get install mysql-server mysql-clientВ процессе установки сервера перед вами появится окошко с предложением задать пароль для root-пользователя MySQL.</li><li>Создание базы данных для работы веб-приложения Django:$ mysql -u root -pВы перейдете в консольный клиент MySQL. Введите пароль root-пользователя, заданный в диалоговом окне на предыдущем шаге. В консольном клиенте введите следующую команду:mysql&gt; CREATE DATABASE 'someapp' DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;Замените «someapp» на название вашего приложения в Django. Задание CHARACTER SET необходимо для корректной работы Django с базой данных.</li><li>Создание отдельного пользователя для Django в MySQL:mysql&gt; CREATE USER 'django'@'localhost' IDENTIFIED BY 'password';mysql&gt; GRANT ALL PRIVILEGES ON 'someapp'.* TO 'django'@'localhost';mysql&gt; FLUSH PRIVILEGES;Укажите свой пароль вместо «password» и название своего приложения вместо «someapp». Второй и третьей командой пользователю django выдаются права на созданную ранее таблицу.</li><li>Нажмите Ctrl-D для выхода из консольного клиента MySQL.</li><li>Установка библиотек и пакетов, необходимых для работы с MySQL из Python:$ sudo apt-get install python3-dev libmysqlclient-dev build-essential$ pip install mysqlclientОбратите внимание, что mysqlclient является форком официального драйвера MySQLdb, но мы используем первый, потому что он поддерживает Python 3. На момент написания статьи MySQLdb не поддерживает третью версию языка.</li><li>Создание дампа данных:$ python manage.py dumpdata --indent=2 --exclude=contenttypes &gt; datadump.jsonПри выполнении этой команды все еще используется SQLite БД — именно из нее выгружаются данные.</li><li>Изменение настроек проекта на использование MySQL:# инструкция с официального сайта djangoproject.com# settings.pyDATABASES = {    'default': {        'ENGINE': 'django.db.backends.mysql',        'OPTIONS': {            'read_default_file': '/path/to/my.cnf',        },    }}# my.cnf[client]database = someappuser = djangopassword = PASSWORDdefault-character-set = utf8Замените «someapp» на название созданной вами для приложения базы данных. Также обратите внимание, что вам необходимо задать корректный путь к файлу в первом фрагменте кода.</li><li>Проведите миграции в Django и загрузите данные:$ python manage.py makemigrations$ python manage.py migrate$ python manage.py loaddata datadump.json</li></ol><p>Теперь ваши данные успешно перенесены в СУБД MySQL. В случае если у вас возникнут трудности при точном следовании этой инструкции, сообщайте в комментариях к этой статье — будем разбираться и добавлять примечания, чтобы сформировать универсальное руководство.</p>]]></content:encoded>
    </item>
    <item>
      <title>Уязвимость в MySQL: простой SELECT дает неограниченные права на исполнение</title>
      <link>https://tproger.ru/articles/mysql_exploit_2016</link>
      <comments>https://tproger.ru/articles/mysql_exploit_2016?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Пётр Соковых]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/mysql_exploit_2016</guid>
      <description><![CDATA[<p>Ошибка CVE-2016-6662 затрагивает все версии MySQL, а также клоны MariaDB и Percona DB: она позволяет запустить стороннюю библиотеку с root-правами.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/mysql_exploit_2016">Уязвимость в MySQL: простой SELECT дает неограниченные права на исполнение</a>»</p>]]></description>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 13 Sep 2016 19:05:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В понедельник <a href="http://legalhackers.com/advisories/MySQL-Exploit-Remote-Root-Code-Execution-Privesc-CVE-2016-6662.html">была опубликована</a> информация от польского исследователя Давида Голунски о двух критических уязвимостях, которые он обнаружил. Уязвимости относятся ко всем версиям MySQL, включая последние (5.5, 5.6 и 5.7), а так же к клонам MySQL — MariaDB и Percona DB.</p><h4>Что за уязвимость?</h4><p>Уязвимость позволяет запустить стороннюю библиотеку с root-правами, а для её эксплуатации необходим доступ к СУБД с возможностью выполнять операции SELECT и FILE. Эта уязвимость получила код <a href="http://www.securityfocus.com/bid/92912">CVE-2016-6662</a>. После её исправления Давид пообещал сообщить о ещё одной уязвимости (которая должна получить код <a href="http://www.securityfocus.com/bid/92911">CVE-2016-6663</a>), которая позволяет делать то же самое, но уже без прав FILE.</p><h4>Самое главное — патчи уже есть?</h4><p>Да, патчи уже есть: 5.5.52, <a href="https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-33.html">5.6.33</a> and <a href="https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-15.html">5.7.15</a>.</p><h4>Отлично. А как это работает?</h4><p>Через изменение конфигурационных файлов с помощью операций логирования. Выглядит это примерно так:</p><p>После чего в файле /etc/my.conf появятся строки:</p><p>И при следующем запуске MySQL указанная библиотека будет запущена от имени суперпользователя. Заметим, что в целом идея атак через правку my.conf не нова. Так, например, в 2003 году в выпуске 3.23.55 уже исправлялась эксплуатация через SELECT * INFO OUTFILE '/var/lib/mysql/my.cnf'. Упоминание этого можно найти в <a href="https://kb.plesk.com/en/2835">описании обновления</a> одного сервиса.</p><h4>И что, уже даже есть готовый эксплойт?</h4><p>Да, <a href="http://legalhackers.com/advisories/MySQL-Exploit-Remote-Root-Code-Execution-Privesc-CVE-2016-6662.html">есть</a>. Однако, он не содержит эксплуатации части обнаруженных Давидом уязвимостей, которые позволили бы проводить атаку без прав FILE, не имея доступа к записи в my.conf.</p><h4>Но это же не полноценная уязвимость, а лишь возможность злоупотребить правами</h4><p>Да, многие придерживаются такой же точки зрения. Тем не менее, права на выполнение запроса SELECT и на запуск исполняемого файла с root-правами — сильно разные вещи, и возможность такого «злоупотребления» должна быть устранена. Заметим, что уже сейчас есть возможность не перезаписывать существующий конфигурационный файл в директории, права на работу с которой есть только у root’а, а создать новый в папке /var/lib/mysql, права на запись в которую (естественно) есть у пользователя mysql по умолчанию.</p><h4>Каким образом исправили уязвимость?</h4><p>Теперь для mysql_safe аргумент --malloc-lib должен принадлежать к одной из следующих директорий: /usr/lib, /usr/lib64, /usr/lib/i386-linux-gnu или /usr/lib/x86_64-linux-gnu. Опции --mysqld и --mysqld-version могут теперь применяться только к запуску из командной строки, и не могу быть описаны в конфигурационных файлах. Кроме этого, файлы с расширениями .ini или .cnf теперь не могут быть использованы для записи функциями логирования.</p>]]></content:encoded>
    </item>
    <item>
      <title>SQLite, MySQL и PostgreSQL: сравниваем популярные реляционные СУБД</title>
      <link>https://tproger.ru/translations/sqlite-mysql-postgresql-comparison</link>
      <comments>https://tproger.ru/translations/sqlite-mysql-postgresql-comparison?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Иван Бирюков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/sqlite-mysql-postgresql-comparison</guid>
      <description/>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 09 Sep 2016 18:32:53 GMT</pubDate>
      <content:encoded><![CDATA[<p>Реляционные базы данных используются уже очень давно. Они стали популярными благодаря успешным реализациям реляционных моделей в системах управления, оказавшимся весьма удобными для работы с данными. В этой статье мы сравним три самые популярные <a href="https://ru.wikipedia.org/wiki/Реляционная_СУБД">реляционные системы управления базами данных</a> (РСУБД): <a href="http://www.sqlite.org">SQLite</a>, <a href="http://www.mysql.com">MySQL</a> и <a href="https://www.postgresql.org">PostgreSQL</a>.</p><h3>Системы управления базами данных</h3><p>Базы данных — это логически смоделированные хранилища любых типов данных. Каждая база данных, не являющаяся бессхемной, следует модели, которая задаёт определённую структуру обработки данных. СУБД — это приложения (или библиотеки), управляющие базами данных различных форм, размеров и типов. Эта статья — часть нашего <a href="https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij">полного путеводителя по SQL</a>.</p><p>Чтобы лучше разобраться в СУБД, ознакомьтесь с <a href="https://tproger.ru/translations/sql-nosql-database-models/">этой статьёй</a>.</p><h3>Реляционные системы управления базами данных</h3><p>Реляционные системы реализуют реляционную модель работы с данными, которая определяет всю хранимую информацию как набор связанных записей и атрибутов в таблице.</p><p>СУБД такого типа используют структуры (таблицы) для хранения и работы с данными. Каждый столбец (атрибут) содержит свой тип информации. Каждая запись в базе данных, обладающая уникальным ключом, передаётся в строку таблицы, и её атрибуты отображаются в столбцах таблицы.</p><h3>Отношения и типы данных</h3><p>Отношения можно определить как математические множества, содержащие наборы атрибутов, отображающие хранящуюся информацию.</p><p>Каждый элемент, формирующий запись, должен удовлетворять определённому типу данных (целое число, дата и т.д.). Различные РСУБД используют разные типы данные, которые не всегда взаимозаменяемы.</p><p>Такого рода ограничения обычны для реляционных баз данных. Фактически, они и формируют суть отношений.</p><h3>Популярные РСУБД</h3><p>В этой статье мы расскажем о 3 наиболее популярных РСУБД:</p><ul><li>SQLite: очень мощная встраиваемая РСУБД.</li><li>MySQL: самая популярная и часто используемая РСУБД.</li><li>PostgreSQL: самая продвинутая и гибкая РСУБД.</li></ul><h3>SQLite</h3><p>SQLite — это изумительная библиотека, встраиваемая в приложение, которое её использует. Будучи файловой БД, она предоставляет отличный набор инструментов для более простой (в сравнении с серверными БД) обработки любых видов данных.</p><p>Когда приложение использует SQLite, их связь производится с помощью функциональных и прямых вызовов файлов, содержащих данные (например, баз данных SQLite), а не какого-то интерфейса, что повышает скорость и производительность операций.</p><h4>Поддерживаемые типы данных</h4><ul><li>NULL: NULL-значение.</li></ul><ul><li>INTEGER: целое со знаком, хранящееся в 1, 2, 3, 4, 6, или 8 байтах.</li></ul><ul><li>REAL: число с плавающей запятой, хранящееся в 8-байтовом формате IEEE.</li></ul><ul><li>TEXT: текстовая строка с кодировкойUTF-8, UTF-16BE или UTF-16LE.</li></ul><ul><li>BLOB: тип данных, хранящийся точно в таком же виде, в каком и был получен.</li></ul><p>Note: для получения более подробной информации ознакомьтесь с <a href="http://www.sqlite.org/datatype3.html">документацией</a>.</p><h4>Преимущества</h4><ul><li>Файловая: вся база данных хранится в одном файле, что облегчает перемещение.</li></ul><ul><li>Стандартизированная: SQLite использует SQL; некоторые функции опущены (RIGHT OUTER JOIN или FOR EACH STATEMENT), однако, есть и некоторые новые.</li></ul><ul><li>Отлично подходит для разработки и даже тестирования: во время этапа разработки большинству требуется масштабируемое решение. SQLite, со своим богатым набором функций, может предоставить более чем достаточный функционал, при этом будучи достаточно простой для работы с одним файлом и связанной сишной библиотекой.</li></ul><h4>Недостатки</h4><ul><li>Отсутствие пользовательского управления: продвинутые БД предоставляют пользователям возможность управлять связями в таблицах в соответствии с привилегиями, но у SQLite такой функции нет.</li></ul><ul><li>Невозможность дополнительной настройки: опять-таки, SQLite нельзя сделать более производительной, поковырявшись в настройках — так уж она устроена.</li></ul><h4>Когда стоит использовать SQLite</h4><ul><li>Встроенные приложения: все портируемые не предназначенные для масштабирования приложения — например, локальные однопользовательские приложения, мобильные приложения или игры.</li></ul><ul><li>Система доступа к дисковой памяти: в большинстве случаев приложения, часто производящие прямые операции чтения/записи на диск, можно перевести на SQLite для повышения производительности.</li></ul><ul><li>Тестирование: отлично подойдёт для большинства приложений, частью функционала которых является тестирование бизнес-логики.</li></ul><h4>Когда не стоит использовать SQLite</h4><ul><li>Многопользовательские приложения: если вы работаете над приложением, доступом к БД в котором будут одновременно пользоваться несколько человек, лучше выбрать полнофункциональную РСУБД — например, MySQL.</li></ul><ul><li>Приложения, записывающие большие объёмы данных: одним из ограничений SQLite являются операции записи. Эта РСУБД допускает единовременное исполнение лишь одной операции записи.</li></ul><h3>MySQL</h3><p>MySQL — это самая популярная из всех крупных серверных БД. Разобраться в ней очень просто, да и в сети о ней можно найти большое количество информации. Хотя MySQL и не пытается полностью реализовать SQL-стандарты, она предлагает широкий функционал. Приложения общаются с базой данных через процесс-демон.</p><h4>Поддерживаемые типы данных</h4><ul><li>TINYINT: очень маленькое целое.</li></ul><ul><li>SMALLINT: маленькое целое.</li></ul><ul><li>MEDIUMINT: целое среднего размера.</li></ul><ul><li>INT или INTEGER: целое нормального размера.</li></ul><ul><li>BIGINT: большое целое.</li></ul><ul><li>FLOAT: знаковое число с плавающей запятой одинарной точности.</li></ul><ul><li>DOUBLE, DOUBLE PRECISION, REAL: знаковое число с плавающей запятой двойной точности.</li></ul><ul><li>DECIMAL, NUMERIC: знаковое число с плавающей запятой.</li></ul><ul><li>DATE: дата.</li></ul><ul><li>DATETIME: комбинация даты и времени.</li></ul><ul><li>TIMESTAMP: отметка времени.</li></ul><ul><li>TIME: время.</li></ul><ul><li>YEAR: год в формате YY или YYYY.</li></ul><ul><li>CHAR: строка фиксированного размера, дополняемая справа пробелами до максимальной длины.</li></ul><ul><li>VARCHAR: строка переменной длины.</li></ul><ul><li>TINYBLOB, TINYTEXT: BLOB- или TEXT-столбец длиной максимум 255 (2^8 – 1) символов.</li></ul><ul><li>BLOB, TEXT: BLOB- или TEXT-столбец длиной максимум 65535 (2^16 – 1) символов.</li></ul><ul><li>MEDIUMBLOB, MEDIUMTEXT: BLOB- или TEXT-столбец длиной максимум 16777215 (2^24 – 1) символов.</li></ul><ul><li>LONGBLOB, LONGTEXT: BLOB- или TEXT-столбец длиной максимум 4294967295 (2^32 – 1) символов.</li></ul><ul><li>ENUM: перечисление.</li></ul><ul><li>SET: множества.</li></ul><h4>Преимущества</h4><ul><li>Простота: MySQL легко устанавливается. Существует много сторонних инструментов, включая визуальные, облегчающих начало работы с БД.</li></ul><ul><li>Много функций: MySQL поддерживает большую часть функционала SQL.</li></ul><ul><li>Безопасность: в MySQL встроено много функций безопасности.</li></ul><ul><li>Мощность и масштабируемость: MySQL может работать с действительно большими объёмами данных, и неплохо походит для масштабируемых приложений.</li></ul><ul><li>Скорость: пренебрежение некоторыми стандартами позволяет MySQL работать производительнее, местами срезая на поворотах.</li></ul><h4>Недостатки</h4><ul><li>Известные ограничения: по определению, MySQL не может сделать всё, что угодно, и в ней присутствуют определённые ограничения функциональности.</li></ul><ul><li>Вопросы надёжности: некоторые операции реализованы менее надёжно, чем в других РСУБД.</li></ul><ul><li>Застой в разработке: хотя MySQL и является open-source продуктом, работа над ней сильно заторможена. Тем не менее, существует несколько БД, полностью основанных на MySQL (например, MariaDB). Кстати, подробнее о родстве MariaDB и MySQL можно из нашего <a href="https://tproger.ru/interview/james-bottomley/">интервью</a> с создателем обеих РСУБД — Джеймсом Боттомли.</li></ul><h4>Когда стоит использовать MySQL</h4><ul><li>Распределённые операции: когда вам нужен функционал бо́льший, чем может предоставить SQLite, стоит использовать MySQL.</li></ul><ul><li>Высокая безопасность: функции безопасности MySQL предоставляют надёжную защиту доступа и использования данных.</li></ul><ul><li>Веб-сайты и приложения: большая часть веб-ресурсов вполне может работать с MySQL, несмотря на ограничения. Этот инструмент весьма гибок и прост в обращении, что только на руку в длительной перспективе.</li></ul><ul><li>Кастомные решения: если вы работаете над очень специфичным продуктом, MySQL подстроится под ваши потребности благодаря широкому спектру настроек и режимов работы.</li></ul><h4>Когда не стоит использовать MySQL</h4><ul><li>SQL-совместимость: поскольку MySQL не пытается полностью реализовать стандарты SQL, она не является полностью совместимой с SQL. Из-за этого могут возникнуть проблемы при интеграции с другими РСУБД.</li></ul><ul><li>Конкурентность: хотя MySQL неплохо справляется с операциями чтения, одновременные операции чтения-записи могут вызвать проблемы.</li></ul><ul><li>Недостаток функций: в зависимости от выбора движка MySQL может недоставать некоторых функций.</li></ul><h3>PostgreSQL</h3><p>PostgreSQL — это самая продвинутая РСУБД, ориентирующаяся в первую очередь на полное соответствие стандартам и расширяемость. PostgreSQL, или Postgres, пытается полностью соответствовать SQL-стандартам ANSI/ISO.</p><p>PostgreSQL отличается от других РСУБД тем, что обладает объектно-ориентированным функционалом, в том числе полной поддержкой концепта ACID (Atomicity, Consistency, Isolation, Durability).</p><p>Будучи основанным на мощной технологии Postgres отлично справляется с одновременной обработкой нескольких заданий. Поддержка конкурентности реализована с использованием MVCC (Multiversion Concurrency Control), что также обеспечивает совместимость с ACID.</p><p>Хотя эта РСУБД не так популярна, как MySQL, существует много сторонних инструментов и библиотек для облегчения работы с PostgreSQL. А если данные неструктурированные? <a href="https://tproger.ru/translations/sql-nosql-database-models">SQL vs NoSQL</a>.</p><h4>Поддерживаемые типы данных</h4><ul><li>bigint: знаковое 8-байтное целое.</li></ul><ul><li>bigserial: автоматически инкрементируемое 8-битное целое.</li></ul><ul><li>bit [(n)]: битовая строка фиксированной длины.</li></ul><ul><li>bit varying [(n)]: битовая строка переменной длины.</li></ul><ul><li>boolean: булевская величина.</li></ul><ul><li>box: прямоугольник на плоскости.</li></ul><ul><li>bytea: бинарные данные.</li></ul><ul><li>character varying [(n)]: строка символов фиксированной длины.</li></ul><ul><li>character [(n)]: строка символов переменной длины.</li></ul><ul><li>cidr: сетевой адрес IPv4 или IPv6.</li></ul><ul><li>circle: круг на плоскости.</li></ul><ul><li>date: календарная дата.</li></ul><ul><li>double precision: число с плавающей запятой двойной точности.</li></ul><ul><li>inet: адрес хоста IPv4 или IPv6.</li></ul><ul><li>integer: знаковое 4-байтное целое.</li></ul><ul><li>interval [fields] [(p)]: временной промежуток.</li></ul><ul><li>line: бесконечная прямая на плоскости.</li></ul><ul><li>lseg: отрезок на плоскости.</li></ul><ul><li>macaddr: MAC-адрес.</li></ul><ul><li>money: денежная величина.</li></ul><ul><li>path: геометрический путь на плоскости.</li></ul><ul><li>point: геометрическая точка на плоскости.</li></ul><ul><li>polygon: многоугольник на плоскости.</li></ul><ul><li>real: число с плавающей запятой одинарной точности.</li></ul><ul><li>smallint: знаковое 2-байтное целое.</li></ul><ul><li>serial: автоматически инкрементируемое 4-битное целое.</li></ul><ul><li>text: строка символов переменной длины.</li></ul><ul><li>time [(p)] [without time zone]: время суток (без часового пояса).</li></ul><ul><li>time [(p)] with time zone: время суток (с часовым поясом).</li></ul><ul><li>timestamp [(p)] [without time zone]: дата и<b> </b>время (без часового пояса).</li></ul><ul><li>timestamp [(p)] with time zone: дата и время (с часовым поясом).</li></ul><ul><li>tsquery: запрос текстового поиска.</li></ul><ul><li>tsvector: документ текстового поиска.</li></ul><ul><li>txid_snapshot: снэпшот ID пользовательской транзакции.</li></ul><ul><li>uuid: уникальный идентификатор.</li></ul><ul><li>xml: XML-данные.</li></ul><h4>Преимущества</h4><ul><li>Полная SQL-совместимость.</li></ul><ul><li>Сообщество: PostgreSQL поддерживается опытным сообществом 24/7.</li></ul><ul><li>Поддержка сторонними организациями: несмотря на очень продвинутые функции, PostgreSQL используется в многих инструментах, связанных с РСУБД.</li></ul><ul><li>Расширяемость: PostgreSQL можно программно расширить за счёт хранимых процедур.</li></ul><ul><li>Объектно-ориентированность: PostgreSQL — не только реляционная, но и объектно-ориентированная СУБД.</li></ul><h4>Недостатки</h4><ul><li>Производительность: В простых операциях чтения PostgreSQL может уступать своим соперникам.</li></ul><ul><li>Популярность: из-за своей сложности инструмент не очень популярен.</li></ul><ul><li>Хостинг: из-за вышеперечисленных факторов проблематично найти подходящего провайдера.</li></ul><h4>Когда стоит использовать PostgreSQL</h4><ul><li>Целостность данных: если приоритет стоит на надёжность и целостность данных, PostgreSQL — лучший выбор.</li></ul><ul><li>Сложные процедуры: если ваша БД должна выполнять сложные процедуры, стоит выбрать PostgreSQL в силу её расширяемости.</li></ul><ul><li>Интеграция: если в будущем вам предстоит перемещать всю базу на другое решение, меньше всего проблем возникнет с PostgreSQL.</li></ul><h4>Когда не стоит использовать PostgreSQL</h4><ul><li>Скорость: если всё, что нужно — это быстрые операции чтения, не стоит использовать PostgreSQL.</li></ul><ul><li>Простые ситуации: если вам не требуется повышенная надёжность, поддержка ACID и всё такое, использование PostgreSQL — это стрельба из пушки по мухам.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Чем PostgreSQL лучше других СУБД</title>
      <link>https://tproger.ru/links/what-postgresql-has-over-other-sql-databases</link>
      <comments>https://tproger.ru/links/what-postgresql-has-over-other-sql-databases?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Артём Артемьев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/links/what-postgresql-has-over-other-sql-databases</guid>
      <description><![CDATA[<p>Объектно-реляционная СУБД ведёт историю с 1986 года, когда в Беркли создали первую версию Postgres, и стала одной из самых продвинутых open-source.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/links/what-postgresql-has-over-other-sql-databases">Чем PostgreSQL лучше других СУБД</a>»</p>]]></description>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Интересные ссылки]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 26 Oct 2015 19:07:09 GMT</pubDate>
      <content:encoded><![CDATA[<p>PostgreSQL — это объектно-реляционная СУБД, которая ведет свою историю с 1986 года, когда в университете Беркли была создана ее первая версия (тогда она еще называлась просто Postgres). За долгие годы эта СУБД стала одной из самых продвинутых в мире open-source. О том, что ее отличает от MySQL, MariaDB и других — читайте в <a href="https://www.compose.io/articles/what-postgresql-has-over-other-open-source-sql-databases/">этой статье</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Избегаем часто встречающихся ошибок при работе с MySQL</title>
      <link>https://tproger.ru/articles/avoid-mistakes-with-mysql</link>
      <comments>https://tproger.ru/articles/avoid-mistakes-with-mysql?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Типичный программист]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/avoid-mistakes-with-mysql</guid>
      <description><![CDATA[<p>Подборка советов по проектированию базы данных MySQL, поиску и запросам: типичные промахи разработчиков и способы их не повторять.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/avoid-mistakes-with-mysql">Избегаем часто встречающихся ошибок при работе с MySQL</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 10 Sep 2015 23:46:14 GMT</pubDate>
      <content:encoded><![CDATA[<p>Работа с базой данных — зачастую самое слабое место в производительности многих web-приложений. И часто можно заметить, как на одни и те же грабли наступают разработчики при проектировании базы данных. Данная подборка советов поможет вам избежать многих ошибок и узнать для себя много полезного.</p><h3>Общее</h3><ul><li>Под каждую отдельную базу данных желательно создавать отдельного пользователя.</li><li>Кодировка базы может быть любой, если она UTF-8.</li><li>В большинстве случаев лучше использовать движок InnoDB.</li><li>В PHP лучше забыть про сильно устаревшее расширение MySQL и по возможности использовать PDO или MySQLi.</li><li>Без особой нужды не стоит открывать MySQL наружу. Лучше сделать проброс портов:ssh -fNL LOCAL_PORT:localhost:3306 REMOTE_USER@REMOTE_HOST</li><li>Используйте подсказки от PROCEDURE ANALYSE(), который анализирует структуру вашей таблицы и дает советы по оптимизации. Следует заметить, что это возможно только при наличии реальных данных в таблице, так как анализ происходит на их основе.</li><li>Лучше перейти на <a href="https://mariadb.org/">MariaDB</a> и забыть про MySQL.</li></ul><h3>Поиск и запросы</h3><ul><li>Если при обращении к таблице вам нужна одна-единственная строка, то используйте LIMIT 1. Использование LIMIT 1 будет оптимальнее, так как база данных остановит выборку записей сразу же после нахождения строки вместо того, чтобы выбирать всю таблицу или индекс.$r = mysql_query("SELECT * FROM user WHERE state = 'Alabama' LIMIT 1");if (mysql_num_rows($r) &gt; 0) { ... }</li><li>Помимо обычного индекса строк, вы можете проиндексировать любые столбцы в таблице. Это даст прирост производительности при поиске.</li><li>Не используйте ORDER BY RAND(). Если вам действительно нужен случайный порядок строк в запросе, то есть много различных способов сделать это иначе. Вам нужно будет написать дополнительный код, однако вы избавитесь от слабого места в производительности. ORDER BY RAND() экспоненциально замедляется при росте базы данных.</li><li>Избегайте использования SELECT *. Чем больше данных считывается из таблицы, тем медленнее запрос, что, в свою очередь, увеличивает время работы с хранилищем данных. Также, если сервер БД установлен отдельно от web-сервера, то будет большая задержка при передаче данных по сети. Лучше делать следующим образом:$r = mysql_query("SELECT username FROM user WHERE user_id = 1");$d = mysql_fetch_assoc($r);echo «Welcome {$d['username']}»;</li></ul><h3>Работа с данными</h3><ul><li>Если система 32-битная, то нет смысла ставить свойство UNSIGNED для типа INTEGER, так как такие большие числа в PHP не поддерживаются. Но если вы используете 64-битную систему, то в этом случае PHP поддерживает большие числа, вплоть до BIGINT со знаком.</li><li>Связанные таблицы «Foreign keys» должны иметь сходство по структуре ключей.</li><li>Для хранения булевых значений лучше всего использовать TINYINT(1).</li><li>Денежные единицы лучше всего хранить в целых числах и работать только с целыми числами. Например, числом копеек, чтобы 100 означало один рубль.</li></ul><h3>Работа со строками</h3><ul><li>Лучшая кодировка для большинства баз данных — UTF-8.</li><li>Тип TEXT вмещает в себя только 64 Кб. Для того, чтобы вместить более объемные тексты, нужно использовать LONGTEXT.</li><li>В версиях MySQL до 5.0.3 VARCHAR была ограничена 255 символами, однако в более старших версиях ограничением является 65535 символов.</li></ul><h3>Работа с датами</h3><ul><li>При сравнении DATETIME и TIMESTAMP не забывайте делать преобразование типов:SELECT * FROM table WHERE `datetime` = DATE(`timestamp`)</li><li>Так как TIMESTAMP хранится в виде UNIX_TIMESTAMP, есть возможность выставить автоматическое обновление колонки.</li><li>Типы данных DATE, TIME, DATETIME выводятся в виде строк, поэтому поиск и сравнение различных дат происходит через преобразование.</li></ul><h3>Работа с перечислениями</h3><ul><li>Для перечислений правильно использовать тип ENUM. Это очень быстрый и компактный тип поля, в котором значения хранятся как в TINYINT, но отображаются как в строковом поле.</li><li>Как и для любой строки, для перечислений можно ставить значение по умолчанию.</li><li>Поле с перечислением хранится как число, поэтому скорость работы довольно высокая.</li></ul><h3>Работа с бэкапами</h3><p>Лучше использовать бэкап с дополнительными опциями -Q, -c, -e:</p><ul><li>-Q оборачивает имена обратными кавычками.</li><li><b>-c</b> делает полную вставку, включая имена колонок.</li><li><b>-e</b> делает расширенную вставку.</li></ul><p>В результате итоговый файл получается меньше, и создается он чуть быстрее.</p><h3>Отладка</h3><ul><li>Если запросы работают медленно, то можно попробовать включить лог для медленных запросов в /etc/mysql/my.cnf, а потом оптимизировать запросы через EXPLAIN.</li><li>Чтобы наблюдать как за запросами, так и в целом за работой сервера, удобно использовать программу Mytop.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Как использовать базу данных MySQL в Java</title>
      <link>https://tproger.ru/translations/java-jdbc-example</link>
      <comments>https://tproger.ru/translations/java-jdbc-example?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Типичный программист]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/java-jdbc-example</guid>
      <description><![CDATA[<p>Пошаговое руководство по подключению базы данных MySQL к Java-приложению через JDBC. Примеры SELECT, INSERT-запросов и обработки ошибок соединения.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/java-jdbc-example">Как использовать базу данных MySQL в Java</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Обучение программированию]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 24 Jun 2015 10:46:15 GMT</pubDate>
      <content:encoded><![CDATA[<p>В этой статье мы научимся подключаться к базе данных MySQL из Java-кода и выполнять простые запросы для получения и обновления данных. Для того, чтобы получить доступ к базе данных, мы будем использовать JDBC (Java Database Connectivity) API, который входит в стандартную библиотеку Java. JDBC позволяет подключиться к любой базе данных: Postgres, MySQL, SQL Server, Oracle и т. д. — при наличии соответствующей реализации драйвера, необходимого для подключения. Для базы данных MySQL мы будем использовать <a href="http://javarevisited.blogspot.com/2012/05/different-types-of-jdbc-drivers-in-java.html">драйвер Type 4 JDBC</a> из пакета mysql-connector-java-5.1.23-bin.jar. Он написан на чистой Java, а значит, нам не понадобятся какие-либо нативные библиотеки или ODBC-мост. Все, что нам надо будет сделать — это положить JAR-файл в директорию, содержащуюся в CLASSPATH. JAR-файл содержит класс com.mysql.jdbc.Driver, необходимый для подключения к MySQL. Если его не окажется в CLASSPATH, во время выполнения программы выбросится исключение java.lang.ClassNotFoundException, поэтому убедитесь, что вы правильно настроили пути.</p><p><b>Ключевые выводы:</b><br />— JDBC API позволяет подключаться к MySQL из Java через стандартную библиотеку без сторонних фреймворков<br />— Для подключения достаточно драйвера mysql-connector-java в CLASSPATH и строки соединения jdbc:mysql://host:port/db<br />— Всегда закрывайте Connection, Statement и ResultSet в finally-блоке или используйте try-with-resources<br />— Для чтения данных используйте executeQuery(), для записи — executeUpdate()<br />— В боевом коде заменяйте Statement на PreparedStatement для защиты от SQL-инъекций</p><p>Кстати, если вы ищете хорошую книгу по использованию JDBC, обратите внимание на <a href="http://www.amazon.com/Practical-Database-Programming-Java-Ying/dp/0470889403?tag=javamysqlanta-20">Practical Database Programming with Java (Ying Bai)</a>. Это относительно новая книга, и в ней рассматриваются две самые популярные базы данных: Oracle и SQL Server 2008. В книге используется IDE NetBeans для примеров и описываются все инструменты, необходимые для работы с базами данных в Java. Это отличная книга для начинающих и опытных программистов.</p><h2>Подключаем базу данных MySQL с помощью JDBC</h2><p>Для того, чтобы подключить базу данных MySQL, нам потребуется четыре вещи:</p><ol><li>Строка подключения JDBC (например:<br />jdbc:mysql://localhost:3306/test).</li><li>Имя пользователя (root).</li><li>Пароль (root).</li><li>База данных с некоторым количеством таблиц для примера (например, база данных книг).</li></ol><p>Строка подключения для MySQL начинается с jdbc:mysql. Это название протокола соединения, за которым следуют хост и порт подключения, на которых запущена база данных. В нашем случае это localhost с портом по умолчанию 3306 (если вы его не поменяли при установке). Следующая часть — test — имя базы данных, которая уже существует в MySQL. Мы можем создать таблицу Books:</p><p>и наполнить её хорошими книгами:</p><h2>Программа на Java для работы с базой данных</h2><p>Теперь давайте напишем программу на Java, которая будет подключаться к нашей базе данных, запущенной на localhost. Важно помнить о том, что необходимо закрывать соединение, запросы и результат выполнения после завершения работы с ними. Также важно закрывать их в finally-блоке, со своей try/catch оберткой, поскольку сам метод close() может кинуть исключение, что приведет к утечке ресурсов. За подробной информацией вы можете обратиться к <a href="http://javarevisited.blogspot.co.uk/2014/10/right-way-to-close-inputstream-file-resource-in-java.html">этой статье</a>. Кроме того, вы можете использовать обертку try-with-resource, которая появилась в Java 7. Более того, это стандартный способ работы с ресурсами в Java 1.7.</p><p>При первом запуске у вас, возможно, будет ошибка No suitable driver found for jdbc:mysql, если драйвера MySQL нет в CLASSPATH:</p><p>Добавим нужный JAR-файл в путь и снова запустим программу. Другая частая ошибка — указать таблицу в строке соединения: jdbc:mysql://localhost:3306/test/book. В этом случае вылетит следущее исключение:</p><p>Успешный запуск программы выведет на экран следующее:</p><p>Результат верный, поскольку у нас в таблице только две книги: <a href="http://www.amazon.com/dp/0321356683/?tag=javamysqlanta-20">Effective Java</a> и Java Concurrency in Practice.</p><p>Кстати, если у вас был драйвер при компиляции, но отсутствует при запуске, вы получите исключение java.lang.ClassNotFoundException: com.mysql.jdbc.Driver. О том, как исправить эту ошибку, вы можете прочитать <a href="http://javarevisited.blogspot.sg/2012/01/javasqlsqlexception-invalid-column.html">здесь</a>.</p><h2>Получаем данные с помощью SELECT-запроса в JDBC</h2><p>Для получения данных из БД вы можете выполнить <a href="http://java67.blogspot.sg/2013/04/10-frequently-asked-sql-query-interview-questions-answers-database.html">SELECT-запрос</a>. В первом примере мы уже его использовали, но получили только количество строк. Теперь мы вернем сами строки. Большая часть программы останется без изменений, за исключением SQL-запроса и кода, возвращающего данные из объекта ResultSet:</p><p>Этот код выведет на экран следующее:</p><p>Тут есть пара моментов, на которые следует обратить внимание. Метод rs.getInt(1) используется для получения столбца с целочисленным типом, в нашем случае это столбец id. Индексы в JDBC <a href="http://javarevisited.blogspot.sg/2012/01/javasqlsqlexception-invalid-column.html">начинаются с единицы</a>, поэтому rs.getInt(1) вернет значение первого столбца как целое число. В случае, если вы укажете неверный индекс (многие разработчики вызывают rs.getInt(0) для получения первого столбца), выбросится исключение InvalidColumnIndexException. Доступ к столбцам по индексу чреват ошибками, поэтому лучше использовать имя столбца, например, rs.getInt("id"). Подробнее об этом вы можете прочитать в <a href="http://javarevisited.blogspot.com/2012/08/top-10-jdbc-best-practices-for-java.html">этой статье</a>. Метод getString() используется для получения строковых значений из базы (например, VARCHAR). Цикл будет выполняться, пока rs.next() не вернет false. Это значит, что строки закончились. В нашем случае в таблице две строки, поэтому цикл выполнится два раза, выводя информацию о книгах из таблицы на экран.</p><h2>Добавляем данные с помощью INSERT-запроса в JDBC</h2><p>Добавление данных мало отличается от их получения: мы просто используем INSERT-запрос вместо SELECT-запроса и метод executeUpdate() вместо executeQuery(). Этот метод используется для запросов INSERT, UPDATE и DELETE, а также для SQL DDL выражений, таких как CREATE, ALTER или DROP. Эти команды не возвращают результата, поэтому мы убираем все упоминания ResultSet'а в коде и изменяем запрос соответственно:</p><p>После запуска программы вы можете проверить таблицу в СУБД. На этот раз вы увидите три записи в таблице:</p><p>Теперь вы умеете подключаться к MySQL из Java-приложения и выполнять SELECT, INSERT, DELETE и UPDATE-запросы так же, как и в MySQL GUI. Для подключения мы используем объект Connection, для чтения результатов запроса — ResultSet. Убедитесь перед подключением, что сервер MySQL запущен и mysql-connector-java-5.1.17-bin.jar находится в CLASSPATH, чтобы избежать ClassNotFoundException.</p><p>Когда разберетесь с подключением и простыми запросами, имеет смысл изучить, как использовать подготавливаемые запросы <i>(Prepared Statement)</i> в Java для <a href="http://javarevisited.blogspot.sg/2012/03/why-use-preparedstatement-in-java-jdbc.html">избежания SQL-инъекции</a>. В боевом коде всегда следует использовать подготавливаемые запросы и связывание переменных.</p><p>Если вам понравилось это руководство и не терпится узнать больше о подключении и работе с базой данных из Java-программ, обратите внимание на следующие статьи:</p><ul><li><a href="http://javarevisited.blogspot.com/2012/04/java-program-to-connect-oracle-database.html">Как подключиться к БД Oracle из Java-приложения</a>;</li><li><a href="http://javarevisited.blogspot.com/2014/04/Connected-vs-disconnected-rowsetprovider-rowsetfactory-and-rowset-JDBC-Java.html">Отличия межу Connected RowSet и Disconnected RowSet в Java</a>;</li><li><a href="http://javarevisited.blogspot.com/2012/06/jdbc-database-connection-pool-in-spring.html">Как использовать пул соединений в Spring</a>;</li><li><a href="http://javarevisited.blogspot.com/2012/01/improve-performance-java-database.html">5 способов улучшить производительность БД в приложениях на Java</a>;</li><li><a href="http://javarevisited.blogspot.com/2012/04/difference-between-javautildate-and.html">Отличия между java.util.Date и java.sql.Date в Java</a>;</li><li><a href="http://javarevisited.blogspot.com/2013/01/jdbc-batch-insert-and-update-example-java-prepared-statement.html">Как выполнить INSERT или UPDATE, используя пакетные запросы JDBC</a>;</li><li><a href="http://javarevisited.blogspot.com/2012/12/top-10-jdbc-interview-questions-answers.html">Десять вопросов по JDBC на собеседованиях</a>.</li></ul><h2>Полезные ссылки</h2><ul><li>Если у вас нет базы данных MySQL, вы можете ее скачать <a href="http://dev.mysql.com/downloads/file.php?id=455551">здесь</a>;</li><li>Если у вас нет драйвера MySQL для JDBC, вы можете скачать его <a href="http://www.mysql.com/products/connector/">отсюда</a>;</li><li>Рекомендованную книгу Practical Database Programming with Java можно купить на <a href="http://www.amazon.com/Practical-Database-Programming-Java-Ying/dp/0470889403?tag=javamysqlanta-20">Amazon</a>.</li></ul><h2>Часто задаваемые вопросы</h2><p><b>Какой JDBC-драйвер нужен для MySQL?</b><br />Для подключения к MySQL из Java используется драйвер mysql-connector-java (MySQL Connector/J). Это драйвер Type 4, написанный на чистой Java. Скачайте JAR-файл с официального сайта MySQL и добавьте его в CLASSPATH вашего проекта. Если вы используете Maven, добавьте зависимость mysql:mysql-connector-java в pom.xml.</p><p><b>Как исправить ошибку No suitable driver found?</b><br />Эта ошибка означает, что JDBC-драйвер MySQL не найден в CLASSPATH. Убедитесь, что JAR-файл mysql-connector-java добавлен в путь к классам. Также проверьте строку подключения — она должна начинаться с jdbc:mysql:// и не содержать имени таблицы (только хост, порт и имя базы данных).</p><p><b>Чем отличается Statement от PreparedStatement?</b><br />Statement выполняет статические SQL-запросы, а PreparedStatement поддерживает параметризованные запросы с подстановкой значений через placeholder-ы (?). PreparedStatement защищает от SQL-инъекций, работает быстрее при повторных вызовах и автоматически экранирует специальные символы. В боевом коде всегда используйте PreparedStatement.</p><p><b>Нужно ли закрывать Connection, Statement и ResultSet?</b><br />Да, обязательно. Незакрытые ресурсы приводят к утечке соединений и памяти. Закрывайте их в finally-блоке в порядке ResultSet, Statement, Connection. В Java 7 и выше используйте try-with-resources — ресурсы закроются автоматически при выходе из блока.</p><p>Перевод статьи How to Connect to MySQL database in Java with Example</p>]]></content:encoded>
    </item>
  </channel>
</rss>