• Гибкая схема хранения данных в MySQL (JSON)

      Александр Рубин работает в компании Percona и не единожды выступал на HighLoad++, знаком участникам как эксперт в MySQL. Логично предположить, что и сегодня речь пойдет про что-то, связанное с MySQL. Это так, но лишь отчасти, потому что еще мы поговорим про интернет вещей. Рассказ будет наполовину развлекательный, особенно первая его часть, в которой посмотрим на девайс, который Александр создал, чтобы собрать урожай абрикосов. Такова уж натура настоящего инженера — хочешь фруктов, а покупаешь плату.



      Предыстория


      Началось все с простого желания посадить фруктовое дерево на своем участке. Сделать это, казалось бы, очень просто — приходишь в магазин и покупаешь саженец. Но в Америке первый вопрос, который задают продавцы, это сколько дерево получит солнечного света. Для Александра это оказалось гигантской загадкой — совершенно неизвестно, сколько солнечного света на участке.

      Чтобы это узнать, школьник мог бы каждый день выходить во двор, смотреть, сколько солнечного света, и записывать это в блокнотик. Но это не дело — надо все оснастить оборудованием и автоматизировать.
      Читать дальше →
    • MySQL — Использование переменных в запросе

      Довольно часто спрашивают, есть ли аналоги аналитических (оконных) функций в MySQL. Примечание. На момент написания статьи таких аналогов не было, однако статья и ныне представляет собой академический интерес в плане разбора оригинального для MySQL подхода к использованию переменных.

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

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

      Одним из этих средств является уникальный, нехарактерный для прочих СУБД механизм работы с переменными внутри запроса SQL. Мы можем объявить переменную внутри запроса, менять ей значение и подставлять в SELECT для вывода. Причем порядок обработки строк в запросе и, как следствие, порядок присвоения значений переменным можно задать в пользовательской сортировке!

      Предупреждение. В статье подразумевается, что обработка выражений в предложении SELECT осуществляется слева направо, однако официального подтверждения такого порядка обработки в документации MySQL нет. Это необходимо иметь в виду при смене версии сервера. Для гарантии последовательности вычисления можно использовать фиктивный оператор CASE или IF.

      Аналог рекурсии


      Рассмотрим простой пример, который генерирует последовательность Фибоначчи (в последовательности Фибоначчи каждый член равен сумме двух предыдущих, а первые 2 равны единице):
      Читать дальше →
      • +21
      • 5,8k
      • 6
    • DBX: попытка избавиться от составления MySQL запросов

      Давным давно, когда я только начинал изучать PHP и тонкости составления запросов MySQL (2011 год) у меня возникла мысль написать обертку для MySQLi наподобие Doctrine для упрощения синтаксиса обращения к базе данных. На дворе уже 2019 и решил поделиться своим велосипедом на тему ORM.

      И так, это DBX — движок базы данных MySQL для PHP на основе библиотеки MySQLi основанный на запросах вида структурного описания таблиц и полей базы данных в виде обычного массива с функцией статического кэширования запросов и автообновления хэша статики.
      Читать дальше →
    • Сериализация данных на уровне базы

      Привет, Хабр!


      Сидел я как-то и пытался отдать фронту JSON с объектами недвижимости, у которых была масса зависимостей. На бэке стояла Symfony 4, knp pagination и JMSSerializer, ну в принципе стандартные вещи, но проблема в том, что когда ты пытаешься отдать объект со всеми вложенными сущностями и коллекциями, то все начинает тормозить на уровне сериализации этих данных.


      Сначала нужно сделать запрос в базу, потом сериализатор подтянет постепенно все остальное, потом все это будет обернуто в JSON и только потом все вернется на фронт.


      Идея


      У меня появилась идея, а почему бы не возвращать на фронт с бэка сразу JSON напрямую из базы, да, надо написать офигительный SQL, но ведь можно сделать инструмент который это сделает за вас. Я принялся за написание идеи, репозиторий на гитхабе, за основу взята модель данных из доктрины, связи OneToOne, ManyToOne, OneToMany и ManyToMany. Так же этот инструмент легко можно прикрутить к Symfony 4 и он сам себя настроит, в итоге вам нужно будет только заинъектить фабрику QueryBuilderFactory и получить оттуда QueryBuilder для нужной таблицы по классу сущности.


      Так же мой сериализатор использует группы сериализации которые вы можете задать с помощью аннотации Expose на поле сущности, не забудьте так же на сущность навесить аннотацию Table и указать алиас таблицы, лучше использовать те, которые вы обычно задаете.


      Пример генерации SQL


      <?php
      
      use \Mash\MysqlJsonSerializer\QueryBuilder\Table\JoinStrategy\FieldStrategy;
      use \Mash\MysqlJsonSerializer\Wrapper\FieldWrapper;
      use \Mash\MysqlJsonSerializer\QueryBuilder\Table\Table;
      use \Mash\MysqlJsonSerializer\Wrapper\Mapping;
      use \Mash\MysqlJsonSerializer\QueryBuilder\QueryBuilder;
      
      $oneToManyTable = (new Table('advert_group', 'adg', 'adg_id'))
          ->addSimpleField('adg_id')
          ->addSimpleField('adg_name')
      ;
      
      $table = (new Table('estate', 'est', 'est_id'))
          ->addSimpleField('est_id')
          ->addSimpleField('est_name')
          ->addOneToManyField($oneToManyTable, 'advert_groups', new FieldStrategy('adg_estate'));
      
      $mapping = new Mapping();
      $mapping
          ->addMap($table, 'est_id', 'id')
          ->addMap($table, 'est_name', 'name')
          ->addMap($oneToManyTable, 'adg_id', 'id')
          ->addMap($oneToManyTable, 'adg_name', 'name');
      
      $builder = new QueryBuilder($table, new FieldWrapper($mapping));
      $builder
          ->setOffset(2)
          ->setLimit(1);
      
      $sql = $builder->jsonArray();

      В результате будет сгенерирован следующий SQL:


      SELECT JSON_ARRAYAGG(JSON_OBJECT('id',est_res.est_id,'name',est_res.est_name,'advert_groups',(SELECT JSON_ARRAYAGG(JSON_OBJECT('id',adg.adg_id,'name',adg.adg_name)) FROM advert_group adg INNER JOIN estate est_2 ON est_2.est_id = adg.adg_estate WHERE est_2.est_id = est_res.est_id))) FROM (SELECT * FROM estate est  LIMIT 1 OFFSET 2) est_res

      Результат:


      [{"id": 3, "name": "Москва, окская улица, 3к1", "advert_groups": [{"id": 10, "name": "avito-1115362430"}]}]
      Читать дальше →
    • Миграция реального приложения со standalone MySQL на Percona XtraDB Cluster

        image

        К сожалению в интернете довольно мало информации по миграции реальных приложений и продакшн эксплуатации Percona XtraDB Cluster (далее PXC). Своим рассказом я постараюсь исправить эту ситуацию и рассказать о нашем опыте. Тут не будет пошаговой инструкции по установке и статью следует рассматривать не как замену офф документации, а как сборник рекомендаций.
        Читать дальше →
      • DataIncrement — дополнение к возможностям phpMyAdmin

          Когда используешь что-то вроде phpMyAdmin для работы с данными в базе, всегда неудобно что связанное поле отображает просто число из другой таблицы, вместо конкретных данных, которые там прячутся.

          Например, в поле `country_id` стоят числа, а не название страны. Приходится прыгать из таблицы в таблицу. Или писать отдельный sql, что бывает зачастую неудобно, если надо по быстрому. Или с телефона набирать sql запрос не с руки. А если нужно обновить страну из поля `country_id`, то опять прыгать из таблицы в таблицу. Короче — неудобно все это.

          Проще показать в формате было-стало:
          Читать дальше →
        • Как научить MySQL заглядывать в прошлое

            Как научить MySQL заглядывать в прошлое

            В статье речь пойдёт о протоколировании изменений в MySQL. Хочу показать реализацию протоколирования на триггерах и то, какие удивительные вещи можно будет с этим делать.

            Почему на триггерах? Потому что нет доступа к бинарному логу. Реализация с бинарным логом потенциально более производительная, хотя и более сложная в разработке, т.к. требуется парсить лог.

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

            В целом же решение является законченным и комплексным. Может быть внедрено «как есть» и прекрасно справляться со своей задачей.
            Читать дальше →
          • Приглашаем на Voronezh Game Dev Meetup


              17 октября в воронежском офисе Mail.Ru Group пройдёт митап по разработке игр. Разработчики Mail.Ru Group расскажут об интересных методах и инструментах, с которыми им довелось работать, и у вас будет время для обсуждения всех выступлений и обмена опытом.

              Участие бесплатное, регистрация по ссылке.
              Читать дальше →
            • Знакомство с SOCI — C++ библиотекой доступа к базам данных

              • Tutorial

              Вступление


              Сама библиотека довольно таки зрелая, — первый релиз на гитхабе датируется аж 2004-ым годом. Я был удивлён когда Хабр в поисковике не выдал мне ни одной ссылки на статьи, в которых бы упоминалось об этой замечательной библиотеке.


              Произносится как: сОцы, с ударением на первый слог.


              SOCI поддерживает ORM, через специализацию soci::type_conversion.


              Поддержка баз данных (БД) (бэкенды):



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

              Читать дальше →
            • Вечная тема с PHP и MySQL

              Всем привет! Наверняка каждый из тех, кто много и постоянно пишет на PHP сталкивался с вопросом оптимизации и упрощения запросов в базы данных MySQL. Кто-то написал уже себе удобные классы/процедуры, кто-то нашел что-нибудь на просторах сети.

              Поскольку у меня скрипты на PHP все больше и больше начинают сворачиваться к одной задаче — выборке из базы данных и передаче этих данных клиентским Java-скриптам, я себе облегчил участь тем, что создал удобный (для меня, конечно) класс по работе с базами данных MySQL.

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

              Вашему вниманию предлагается класс exDBase, это по сути своей оболочка для класса mysqli. Сразу оговорюсь — я программист начинающий, и готов в комментариях или личных сообщениях получить массу критики за написанный код. Я не очень владею RegExp например, которые сильно бы упростили код, возможно есть и другие претензии. Но, тем не менее…
              Читать дальше →

            Самое читаемое