Рубрика «mysql» - 9

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

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

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

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

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

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

Рассмотрим простой пример, который генерирует последовательность Фибоначчи (в последовательности Фибоначчи каждый член равен сумме двух предыдущих, а первые 2 равны единице):
Читать полностью »

Привет!

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

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

Идея

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

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

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

<?php

use MashMysqlJsonSerializerQueryBuilderTableJoinStrategyFieldStrategy;
use MashMysqlJsonSerializerWrapperFieldWrapper;
use MashMysqlJsonSerializerQueryBuilderTableTable;
use MashMysqlJsonSerializerWrapperMapping;
use MashMysqlJsonSerializerQueryBuilderQueryBuilder;

$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"}]}]

Читать полностью »

Оптимизация реляционных баз данных без даунтайма на примере самой нагруженной БД в Badoo - 1

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

Недавно мы рассказали, как мы оптимизировали PHP-код нашего приложения. Теперь же пришёл черёд статьи про то, как мы полностью изменили внутреннюю структуру самой нагруженной и важной базы данных в Badoo, не потеряв при этом ни одного запроса.
Читать полностью »

Подержанное авто в кредит за 1 минуту - 1

Вместо введения

Как и все интересные истории, эта началась достаточно давно и неожиданно. Однажды наш банк-партнер пришел к нам и сказал: “Ребята, мы научились делать скоринг в нашей системе за одну минуту. Как насчет того, чтобы объединить наши усилия и интегрировать проекты? С нас – решение и кредит, с вас – машины”. Сказать, что мы воодушевились, – ничего не сказать! Мы имели все шансы стать первыми чуть ли не в мире, кто может дать кредит онлайн на подержанное авто за одну минуту (ОДНУ МИНУТУ, КАРЛ)! Ниже я расскажу, что из этого получилось, но для начала расскажу вам, кто такие, собственно, МЫ.Читать полностью »

GitHub использует MySQL в качестве основного хранилища данных для всего, что не связано с git, поэтому доступность MySQL имеет ключевое значение для нормальной работы GitHub. Сам сайт, интерфейс API на GitHub, система аутентификации и многие другие функции требуют доступа к базам данных. Мы используем несколько кластеров MySQL для обработки различных служб и задач. Они настроены по классической схеме с одним главным узлом, доступным для записи, и его репликами. Реплики (остальные узлы кластера) асинхронно воспроизводят изменения главного узла и обеспечивают доступ для чтения.

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

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

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

Высокая доступность MySQL в GitHub - 1Читать полностью »

Привет! Это рассказ о том, что нового в нашем плагине для баз данных. Мы выпускаем его, как отдельный продукт DataGrip, и поставляем почти во все другие наши IDE. Будет много картинок и гифок. Для тех, кому лень их смотреть:

— Поддержка Cassandra
— Создание SQL-файлов из объектов схемы
— Новые инспекции
— Много новых штук в автодополнении
— Работа с источником данных через одно подключение
— Новый поиск
— Высококонтрастная цветовая схема

Спасибо тем, кто пробует EAP-версии и сообщает в наш трекер о проблемах: это помогает не дотащить их до релиза :) Активные пользователи уже получили бесплатные подписки на год.

image
Читать полностью »

Роковые 43 секунды, которые вызвали суточную деградацию сервиса

На прошлой неделе в GitHub произошёл инцидент, который привёл к деградации сервиса на 24 часа и 11 минут. Инцидент затронул не всю платформу, а только несколько внутренних систем, что привело к отображению устаревшей и непоследовательной информации. В конечном счете данные пользователей не были потеряны, но ручная сверка нескольких секунд записи в БД выполняется до сих пор. На протяжении почти всего сбоя GitHub также не мог обрабатывать вебхуки, создавать и публиковать сайты GitHub Pages.

Все мы в GitHub хотели бы искренне извиниться за проблемы, которые возникли у всех вас. Мы знаем о вашем доверии GitHub и гордимся созданием устойчивых систем, которые поддерживают высокую доступность нашей платформы. С этим инцидентом мы вас подвели и глубоко сожалеем. Хотя мы не можем отменить проблемы из-за деградации платформы GitHub в течение длительного времени, но можем объяснить причины произошедшего, рассказать об усвоенных уроках и о мерах, которые позволят компании лучше защититься от подобных сбоев в будущем.
Читать полностью »

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

На GitHub произошёл сбой БД - 1

Читать полностью »

Итак, как наверняка все знают, совсем недавно 1-2 октября в Москве в “Инфопространстве” прошёл DevOpsConfRussia2018. Для тех кто не вкурсе, DevOpsConf — профессиональная конференция по интеграции процессов разработки, тестирования и эксплуатации.

Наша компания также приняла участие в этой конференции. Мы являлись её партнерами, представляя компанию на нашем стенде, а также провели небольшой митап. К слову это было первое наше участие в подобном роде деятельности. Первая конференция, первый митап, первый опыт.

О чём мы рассказывали? Митап был на тему “Бэкапы в Kubernetes”.

Скорее всего услышав это название, многие скажут: “А зачем бэкапить в Kubernetes? Его не нужно бэкапить, он же Stateless”.

Бэкапы Stateful в Kubernetes - 1

Читать полностью »

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

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

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

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

В целом же решение является законченным и комплексным. Может быть внедрено «как есть» и прекрасно справляться со своей задачей.
Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js