# Введение

## Что это?

Всем привет! То, что вы видите, ничто иное, как:

{% hint style="success" %}
**System Analyst Base — База знаний системного аналитика**
{% endhint %}

Данная база знаний призвана помочь начинающим специалистам подготовиться и успешно пройти собеседование на должность системного аналитика.&#x20;

Преимущественный уровень материала: *intern, junior, middle/middle+*.

## Структура

Вначале каждой главы описан блок "Вопросы на которые ответим", это поможет быстро понять, о чем глава и какие вопросы в ней раскрываются. Главы в базе для удобства разбиты на две части: "Soft skills" и "Hard skills". Однако порядок может не соответствовать тому, в котором, обычно спрашивают на собеседованиях.&#x20;

{% hint style="info" %}
База знаний построена по принципу "от общего к частному"
{% endhint %}

## Легенда

:round\_pushpin: — обязательно к изучению (включая все подглавы, если не указано иного)

:paperclip: — дополнительный материал&#x20;

:lock: — темы для уровня middle+ (в разработке)

:closed\_lock\_with\_key: — темы для уровня senior (в разработке)

Так как автор сам еще учится, написанное может содержать ошибки и неточности.

*Приятного (из/об)учения!*


# Продукт

## Вопросы на которые ответим:

* Расскажите про состав команды разработки - какие есть роли и какие функции выполняет каждая из них?
  * Какую роль выполняет системный аналитик в проектах разработки ПО?
  * Чем отличается системный аналитик от бизнес-аналитика?
* Расскажите про процесс разработки (жизненный цикл разработки), который был принят на вашем прошлом месте работы.
  * Какие этапы проходит задача\продукт до выхода в прод?
* Какие методологии бывают? В каких методологиях вам приходилось работать?
  * Чем Waterfall отличается от Agile?
    * Что такое Спринт? Опишите, как строится планирование Спринта
    * Что такое ретро?
    * Что такое груминг?&#x20;
  * Чем Kanban отличается от Scrum?
  * Где можно применять Scrum и где нельзя?
* Как ставятся цели? Расскажите про SMART.


# Роли в IT продукте

Кто и где Я

<div data-full-width="true"><figure><img src="/files/1HmwDfCsYz0Lo35aYiHh" alt=""><figcaption><p>Роли в IT продукте</p></figcaption></figure></div>

## Product manager (PrM)

Product manager —  это специалист, который отвечает за создание продукта и его вывод на рынок. Он должен обладать навыками в области маркетинга, продаж, управления проектами и понимания потребностей пользователей.

Задача специалиста — создать продукт, который удовлетворит потребности пользователей и принесёт компании прибыль.

## Project manager (PM)

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

***

## **Business Analyst (BA)**

Напрямую общается с заказчиками продукта и выясняет их пожелания и требования. Задача бизнес аналитика верхнеуровнево понять, чего хочет заказчик, как он видит продукт, который будет разрабатывать команда, цель у продукта и какие задачи он будет решать. На момент общения с заказчиком бизнес аналитик может предлагать свои идеи по улучшению продукта и совместно с заказчиком формировать так называемый vision[^1].

## :point\_right: **System Analyst (SA)**

Как правило, этот специалист работает в паре с бизнес-аналитиком, но в отличие от него обращает внимание не на то, как должна выглядеть и какие задачи решать система. Главное, что волнует системного аналитика – это то, как система должна работать в различных вариантах использования и какие у нее будут функции. Именно это, с помощью ТЗ и спецификаций, детально описывает системный аналитик проекта.

***

## Architect

Ключевая обязанность архитектора — проектирование архитектуры ПО, т. е. принятие ключевых проектных решений относительно внутреннего устройства программной системы и её технических интерфейсов.

Зачастую, системный аналитик приходит к архитектору за советом, как лучше сделать то или иное нововведение.&#x20;

***

## **Designer**

Designer — этот специалист отвечает за оформление и внешний вид продукта. Именно он «рисует» все элементы продукта, которые видит заказчик в конечном варианте, подбирает цвета и формы.

Существуют два основных типа дизайнеров:

* User Experience Designer (UX): изучает и оценивает, как пользователи относятся к разрабатываемому программному обеспечению. На нем лежит ответственность за то, чтобы продукт был прост в использовании, восприятии ценности, полезности и эффективности. Он продумывает и оценивает процессы и сценарии использования ПО.
* User Interface Designer (UI): разрабатывает визуальную часть пользовательского интерфейса. Основными целями работы UI дизайнера являются: интуитивность восприятия, простота, юзабилити и эстетика интерфейса ПО.

## **Web developer**

Верстальщик — именно благодаря этому специалисту «оживают» макеты, созданные дизайнерами. Эти специалисты создают верстку страниц так, чтобы они правильно отображались с мобильного телефона и с ПК.

***

## **Developer (Dev)**

Developer — это программист, который создает программное обеспечение или приложения. Этот специалист в команде занимается реализацией требований, которые ранее были прописаны системным аналитиком.

## Team Lead

Отвечает за работу группы специалистов.

Team Leader обеспечивает комфортные условия работы коллектива и поддерживает высокий уровень эффективности команды. Этот человек не обязательно должен знать специфику работы команды досконально. Например, Team Leader в группе разработчиков не обязан быть программистом, ему достаточно понимать как организовать работу, понимать процессы, протекающие во время производства.

## Quality Assurance (QA)

Quality Assurance (QA) — это специалист по обеспечению качества продукта или услуги. Он занимается тестированием продукта, находит ошибки и предлагает способы их устранения.

***

## Human Resource (HR)

Human Resource (HR) — это специалист по управлению персоналом. Он занимается подбором сотрудников, организацией обучения, разработкой систем мотивации и оценки эффективности работы персонала. HR также может участвовать в разрешении конфликтов, проведении мероприятий по улучшению корпоративной культуры и управлении кадровым резервом.

Источники:

* <https://tproger.ru/articles/software-company-structure>
* <https://habr.com/ru/articles/695944/>

[^1]: Vision - это образ будущего, к которому стремится компания или организация. Это может быть новая продукция, улучшенные процессы, изменение рынка или достижение определенных целей.


# Системный аналитик (SA)

"Developer should not think - this is the analysts's job"

## Чем занимается системный аналитик?

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

## Обязанности системного аналитика

В процессе реализации проекта системный аналитик первым шагом собирает требования с заказчика. Нужно выяснить, что заказчику нужно от программного обеспечения. Он анализирует эти требования на полноту, непротиворечивость, уточняет проблемные места и проводит дополнительные интервью. На интервью системный аналитик спрашивает заказчика обо всём, в чём сомневается: «А для чего? Какую проблему это решит? А точно ли это надо?»

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

Что делает системный аналитик после того, как составил ТЗ для разработчиков? Он отвечает на вопросы, сопровождает разработку и тестирование. Тестировщики приходят к аналитику с вопросами: «Программа работает так — это правильно или нет?»

Далее системный аналитик демонстрирует результаты работы заказчику. На этом этапе, если того требует заказчик, добавляют обучение пользователей.

На этапе сопровождения системный аналитик отвечает на сложные вопросы пользователей, на которые не может ответить техподдержка.

Задачи системного аналитика разноплановые: общение с заказчиком, анализ требований, описание требований, сопровождение процесса, разбор кейсов. Всегда встречается что-то новое.

## Навыки специалиста

### Soft skills

* **Системное мышление**. Системный аналитик должен на лету понимать, что с чем связано. Системное мышление помогает увидеть, понять смысл и закономерность в последовательностях, которые он наблюдает. Оно помогает специалисту подготовиться к будущему и повлиять на конечный продукт.
* **Коммуникативные навыки**. Системный аналитик должен уметь разговаривать с собеседником на его языке. Например, понять разработчика, чтобы донести до него необходимость реализации тех или иных функций программного обеспечения. С заказчиком же системный аналитик должен говорить на языке бизнеса: понять, чего он хочет и продемонстрировать это понимание. Например, насколько автоматизация важна для выручки.
* **Внимательность, педантичность и здоровый перфекционизм**. Ошибки на этапе анализа самые дорогие по сравнению с ошибками на других этапах. Если системный аналитик допустит ошибку на этом этапе, значит, команда зря потратит ресурсы на разработку и тестирование. А чтобы исправить ошибку, нужно откатываться назад и начинать сначала.
* **Хорошая память**. Системный аналитик должен быть «живым справочником» по проекту, который отвечает на любой вопрос.

### Hard skills

* **Грамотный русский язык**. Системному аналитику приходится много писать и говорить. Важно, чтобы его правильно и легко понимали.
* **Техническая грамотность**. У системного аналитика должны быть базовые знания об информационных системах — computer science. Например, важно понимать, как информационные системы обмениваются данными между собой.
* **SQL на базовом уровне**. SQL (structured query language) — язык структурированных запросов. Его применяют для создания, модификации и управления данными.
* **Диаграммы и нотации**. Диаграммы и нотации необходимы для выполнения работы по анализу, проектированию и улучшению бизнес-процессов и информационных систем.&#x20;
* **Интеграции**. Необходимы для эффективного анализа, проектирования и улучшения информационных систем, которые часто включают в себя множество различных компонентов, взаимодействующих друг с другом.

## Зарплата

По данным [Хабр.Карьера](https://career.habr.com/salaries?spec_aliases\[]=systems_analyst\&isShared=true) зарплата Системных аналитиков в России в 2023 году распределяется следующим образом:

<figure><img src="/files/JRb2QIWv6umBkbFikYoW" alt=""><figcaption><p>Зарплата Системных аналитиков в России 2023</p></figcaption></figure>

Источник: <https://practicum.yandex.ru/blog/kto-takoy-sistemnyi-analitik/#obyazannosti-sistemnogo-analitika>


# Бизнес-аналитик (BA)

## Чем занимается бизнес-аналитик?

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

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

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

## Обязанности бизнес аналитика

Многие навыки бизнес-аналитика звучат как гибкие навыки, но для специалиста в этой сфере являются профессиональными. Потому что важнейшее умение для него — поддерживать коммуникацию с заказчиками и сотрудниками, которые напрямую связаны с процессом. Вот навыки, которые можно считать ключевыми:

### Soft skills

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

Специалисту важно общаться с заказчиком на его языке и задавать правильные вопросы. На старте работы нельзя просто спросить «Чего вы хотите?» — ответ, скорее всего, будет слишком общим и не позволит выделить конкретную потребность заказчика. Поэтому бизнес-аналитик должен через наводящие вопросы выяснить, в чём «боль» клиента.

* **Критическое мышление**. Бизнес-аналитик — специалист, которому никто не подскажет, как сделать процесс лучше. Это от него ждут советов и рекомендаций.

Бизнес-аналитик должен задавать максимум существенных вопросов и постоянно спрашивать себя: всё ли в процессе работает хорошо? Почему процесс устроен именно так? Как можно его улучшить? Вопросы помогают специалисту находить способы усовершенствовать продукт.

* **Системность**. Бизнес-аналитик много общается с заказчиками и сотрудниками компаний, с которыми работает. Часто из интервью он получает много несущественной информации.

Например, во время работы над системой складского хранения бизнес-аналитик разговаривал с кладовщиками. Они рассказали, как водители задерживают рейсы, как путают накладные, как в прошлом месяце часть сотрудников осталась без премии и ещё много всего. Задача бизнес-аналитика — отделить важное от второстепенного и систематизировать информацию.

* **Эмпатия**. Эмпатия помогает бизнес-аналитику общаться с клиентами и другими людьми. Например, специалист занимается оптимизацией системы безопасности и для этого проводит интервью с охранниками. Они понимают, что после обновления системы часть штата сократят, поэтому неохотно отвечают на вопросы. Эмпатия поможет понять их опасения и правильно задать вопросы.

### Hard skills

* **Разработка ПО**. Понимание процессов в разработке ПО — ключевое знание для бизнес-аналитика, так как он работает на стыке бизнеса и IT.&#x20;
* **SQL**. Бизнес-аналитику желательно владеть языком поисковых запросов хотя бы на базовом уровне.&#x20;
* **Excel или гугл-таблицы**. В них заказчики часто хранят данные, поэтому обычно бизнес-аналитик делает расчёты именно там. Ещё в Excel можно составлять графики и диаграммы, а с надстройкой VBA — делать быстрый срез по собранным данным.
* **Нотации построения бизнес-процессов**. Чаще всего это BPML, в госучреждениях бывает EPS. Плюсом будет знание UML — языка моделирования бизнес-процессов.

## Зарплата

По данным [Хабр.Карьера](https://career.habr.com/salaries?qualification=All\&spec_aliases%5B%5D=business_analyst\&isShared=true) зарплата Бизнес-аналитиков по всей России в 2023 году распределяется следующим образом:

<figure><img src="/files/NWkbVfcbFH6jH3m89m14" alt=""><figcaption><p>Зарплата Бизнес-аналитиков в России 2023</p></figcaption></figure>

Источник: <https://practicum.yandex.ru/blog/professiya-biznes-analitika/>


# SA vs BA

Часто на собеседованиях просят объяснить, чем же отличаются или не отличаются обязанности системного аналитика и бизнес-аналитика. Этот раздел призван помочь разобраться в этом вопросе. Также стоит заметить, что бывают случаи (в маленьких компаниях это скорее правило), что один человек выполняет одновременно обе эти роли.&#x20;

## Отличия системного аналитика (SA) от бизнес-аналитика (BA)

| Бизнес-аналитик                                                                                 | Системный аналитик                                           |
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| Внедряет изменения в бизнес-процессы внутри организации                                         | Разрабатывает требования к программному обеспечению          |
| <p>Часто: является членом команды разработки<br>Реже: не является членом команды разработки</p> | Обязательно является членом команды разработки               |
| Бизнес-аналитик может не иметь отношения к IT                                                   | Обязательно IT-специалист                                    |
| Работает в команде с системным аналитиком и говорит, что делать                                 | Работает в команде с бизнес-аналитиком и говорит, как делать |
| Упор на общение с заказчиком                                                                    | Упор на общение с разработчиками                             |
| Должен разбираться в бизнесе                                                                    | Разбираться в бизнесе не обязательно                         |

## Перспективы профессий

У бизнес- и системных  аналитиков есть два возможных варианта карьерного роста: горизонтальный и вертикальный:

* Горизонтальный. Можно перемещаться между смежными областями — например, стать проджект менеджером или продакт-менеджером, либо же для SA - стать архитектром всей системы.
* Вертикальный.&#x20;
  * SA: Вырасти до лида команды или стать системным консультантом.
  * BA: Вырасти до руководителя команды или стать бизнес-консультантом. Ещё один возможный вариант карьерного роста — переход от бизнес-аналитики к моделированию бизнес-процессов с нуля. Специалист, который этим занимается, называется бизнес-архитектором.

<figure><img src="/files/bbUVYsU0V5K1CedfjRg9" alt=""><figcaption><p>Горизонтальный и вертикальный рост в профессиях SA и BA</p></figcaption></figure>

Источник:

* &#x20;<https://practicum.yandex.ru/blog/kto-takoy-sistemnyi-analitik/#obyazannosti-sistemnogo-analitika>


# Другие аналитики

{% embed url="<https://www.youtube.com/watch?v=PJnXeG4Sots>" %}


# Жизненный цикл продукта

{% hint style="info" %}
**Жизненный цикл программного продукта** — это последовательность этапов, через которые проходит программный продукт от его идеи до вывода из эксплуатации. Каждый этап включает определенные действия и задачи, необходимые для успешного выполнения этапа и перехода к следующему этапу.&#x20;
{% endhint %}

Жизненный цикл программного продукта состоит из следующих этапов:

1. **Идея и планирование:** На этом этапе происходит инициация проекта, определяются его цели, задачи и ожидаемые результаты, а также ресурсы, необходимые для его выполнения. Определяются требования к продукту, ставятся цели качества и сроки разработки.
2. **Анализ требований:** На этом этапе проводится подробный анализ требований к продукту. Аналитики собирают и анализируют требования к функциональности, производительности, безопасности, удобству использования и другим аспектам продукта. В результате анализа формируется документация с требованиями к продукту.
3. **Проектирование:** На этом этапе разрабатывается архитектура и дизайн продукта на основе сформулированных требований. Разработчики определяют основные компоненты и модули продукта, их функциональность и связи между ними.
4. **Разработка:** На этом этапе происходит создание кода продукта. Разработчики создают и тестируют каждый модуль продукта, выполняют интеграцию компонентов и тестирование в целом.
5. **Тестирование и отладка:** На этом этапе проводятся тесты продукта, находятся и исправляются ошибки. Тестирование может быть автоматическим или проводиться вручную. Цель этого этапа — проверить, что продукт работает правильно и соответствует требованиям, определенным на предыдущих этапах.
6. **Внедрение и сопровождение:** На этом этапе продукт готов к выпуску на рынок. Он может быть установлен на сервере или распространяться через интернет. Клиенты начинают использовать продукт, а разработчики предоставляют техническую поддержку и исправляют ошибки.
7. **Оптимизация и обновление:** На этом этапе продукт постоянно улучшается и обновляется. Разработчики работают над улучшением функциональности, исправлением ошибок, оптимизацией производительности и обеспечением совместимости продукта с новыми технологиями и требованиями рынка. Обновления могут выпускаться регулярно или по мере необходимости.

Источник: <https://testengineer.ru/product-development-life-cycle/>


# Методологии разработки

## Общее

Существует 7 методологий разработки программного обеспечения:

1. Waterfall Model (каскадная модель или «водопад»)
2. V-Model
3. Incremental Model (инкрементная модель)
4. RAD Model (rapid application development model или быстрая разработка приложений)
5. Agile Model (гибкая методология разработки)
   * Scrum (фреймворк для управления проектами)
   * Kanban (метод управления разработкой)
6. Iterative Model (итеративная или итерационная модель)
7. Spiral Model (спиральная модель)

Рассмотрим основные из них, которые чаще всего фигурируют в современных IT компаниях.&#x20;


# Waterfall

{% hint style="info" %}
**Waterfall** - классическая поэтапная методология, в которой каждый следующий шаг начинается только после завершения предыдущего. В отличие от Agile каскадная модель не допускает изменений в этапах разработки.
{% endhint %}

<div data-full-width="true"><figure><img src="/files/s6K5y5JQj4U0Qa7g011N" alt=""><figcaption><p>Основные этапы методологии Waterfall</p></figcaption></figure></div>

## Преимущества

* Оценка затрат и сроков до начала проекта. Все требования четко проговариваются на начальном этапе и не изменяются в течение всего процесса. Предсказуемость позволяет точно оценить будущие расходы.
* Постоянный контроль процессов и предсказуемость. Цели и задачи проекта понятны для разработчиков и не вызывают дополнительных вопросов).
* Документация каждого этапа. Это позволяет создавать базу для других проектов и предоставлять отчетность заказчику в любое время.

## Недостатки

* Сложно исправить ошибки. Тестирование проходит только на последних этапах разработки, поэтому возможные недочеты необходимо предусмотреть заранее.
* Отсутствие обратной связи от заказчика на протяжении большей части проекта. Заказчик принимает участие в обсуждении целей проекта и возвращается, чтобы оценить финальный результат, который может его полностью не удовлетворить.
* Высокая стоимость исправлений. Любая ошибка приведет к необходимости переделывать весь проект. Избежать подобных проблем помогают сильные и дорогие бизнес-аналитики, которые способны точно перевести задачи бизнеса на ИТ язык.

## Где применяется

Каскадная модель будет давать отличный результат только в проектах с четко и заранее определенными требованиями и способами их реализации.&#x20;

Зачастую Waterfall-модель не используется в современных IT компаниях , а лишь противопоставляется новомодной методологии Agile, о которой и пойдет речь дальше.&#x20;

Источник: <https://stecpoint.ru/Practices-Methodologies/>


# Agile

XX.02.2001

В противовес Waterfall, Agile разработка позволяет вносить изменения на каждом этапе проекта, адаптировать проект под требования владельца продукта, снижать финансовые риски и быстро запускать продукт на рынок.

Методология Agile строиться на основных правилах, которые стараются учесть все участники процесса.

## Основные идеи Agile

* Люди и взаимодействие важнее процессов и инструментов
* Работающий продукт важнее исчерпывающей документации
* Сотрудничество с заказчиком важнее согласования условий контракта
* Готовность к изменениям важнее следования первоначальному плану

Источник:

* Манифест Agile: <https://agilemanifesto.org/iso/ru/manifesto.html>


# Scrum

популярно, быстро, эффективно

Если Agile – это принципы и философия, то Scrum – это набор конкретных правил и регламентов, которые говорят о том, как именно организовывать работу.&#x20;

{% hint style="info" %}
**Scrum** – модель управления разработкой с гибкой организацией работы внутри команды, направленной на создание новых сложных продуктов. Scrum позволяет развивать проект в тесном сотрудничестве с заказчиком, постоянно корректируя характеристики продукта и показывая результат на каждом этапе разработки.
{% endhint %}

<figure><img src="/files/N184K5bLuJzSvd3wMEyu" alt="" width="563"><figcaption><p>Цикл разработки по Scrum</p></figcaption></figure>

## Scrum роли в команде

* Product owner – управляет бэклогом. Backlog – набор требований, которые надо реализовать для того, чтобы продукт был готов. Задачи product owner собрать BackLog, сделать его понятным для команды, выставить приоритеты. Backlog постоянно обновляется в зависимости от текущих целей разработки.
* Scrum master – координирует команду. Специалист по Scrum, досконально знает этапы, церемонии, артефакты Scrum разработки. Зачастую эту роль выполняет Product owner.
* Development team – команда разработки (разработчики, аналитики, тестировщики). Люди должны быть кросс-функциональны, т.е. иметь унифицированные компетенции (каждый должен уметь делать все).

## Scrum события

* **Sprint** – время, за которое создается инкремент продукта — готовый для конечного пользователя продукт. Само часто встречающиеся по длине спринты - это 1 или 2 недели.&#x20;
* **Планирование Sprint’а** – на этой встрече решается, каким будет инкримент, и как организовать работу, чтобы успеть сделать все задачи. Целью планирования является формирование бэклога спринта из бэклога продукта. В планировании спринта участвуют все члены Scrum команды.
* **Ежедневные митинги (daily meeting)** – встречи, на которых обсуждается, что сделано за предыдущий день, что будет делаться сегодня, какие проблемы мешают достижению целей спринта.
* **Обзор спринта (Sprint review meeting)** — встреча с подведением итогов спринта, демонстрация инкремента продукта для product owner или заказчика. В обзоре спринта участвуют все члены Scrum команды.
* **Ретроспектива** – на нем высказываются о прошедшем спринте: что было сделано хорошо, то надо улучшить в следующем спринте. Чаще всего проходит в рамках Sprint review meeting.
* **Груминг (Grooming)** – это процесс в разработке ПО, который помогает уточнять и приоритезировать задачи в проекте. Он включает в себя команду участников, которые создают и анализируют задачи или пользовательские истории в беклоге проекта, а затем определяют, какие из них являются наиболее важными или должны быть выполнены первыми.

## Преимущества

* Простота внедрения методологии в команду
* Эффективное взаимодействие между участниками проекта. Процесс принятия решений полностью зависит только от членов команды. Все внутренние процессы регулируют сами разработчики. Это позволяет всем участникам проекта четко понимать свои функции и задачи.
* Возможность быстрого запуска проекта с наиболее приоритетными функциями и минимально возможным бюджетом.
* Ежедневный контроль над ходом работ, и более гибкий контроль над бюджетом проекта.
* Малую вероятность провала разработки из-за частых совещанием с заказчиком продукта.
* Возможность вносить коррективы в техническое задание по ходу реализации проекта.

## Недостатки

* Большое количество совещаний. (порядка 15-20% рабочего времени)
* Необходимость кросс-функциональности команды с высокой квалификацией.
* Сложности при заключении договоров. Scrum в принципе не подразумевает наличие фиксированного бюджета и фиксированного технического задания, что затрудняет юридическое оформление такого рода договоренностей.

## Где используется

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

Источники:

* <https://vc.ru/u/752307-karina-gorbunova/218436-kanban-agile-scrum-lean-gibkie-metodologii-razrabotki>
* <https://stecpoint.ru/Practices-Methodologies/>
* <https://agaltsovav.ru/docs/development-managment/grooming/>


# Kanban

{% hint style="info" %}
**Kanban** - подход к разработке ПО по методике Agile, который подразумевает открытость всех рабочих процессов и постоянное улучшение производительности. Каждый член команды выполняет индивидуальный набор задач.
{% endhint %}

<figure><img src="/files/v3R98dCuVIPxFF8zg4uM" alt="" width="375"><figcaption><p>Цикл разработки по Kanban</p></figcaption></figure>

## Преимущества

* Наглядная визуализация задач на Канбан-доске.
* Высокая концентрация на текущей работе. Команда фокусируется на конкретной задаче и направляет все усилия на ее решение. Приоритетность задач может меняться.
* Быстрое устранение проблем. Все члены команды могут отслеживать прогресс и давать обратную связь, которая помогает оперативно исправлять ошибки.
* Оптимизация издержек. Канбан позволяет анализировать и прогнозировать точное время, необходимое для реализации проекта.

## Недостатки

* Не удовлетворяет требованиям больших команд. Метод не предназначен для групп численностью больше 5 человек, и команд, где сотрудники не знают функции друг друга. В таких условиях невозможно эффективно контролировать реализацию проекта.

Главное преимущество Канбана это Канбан-доска, на которой четко видно в каком состоянии находится задача и, что не мало важно, сколько задача находится в таком состоянии. В связи с чем, на данный момент Канбан зачастую используется как приложение к Scrum, просто для визуализации бэклога спринта.&#x20;

Источник: <https://stecpoint.ru/Practices-Methodologies/>


# Целеполагание


# SMART

{% hint style="info" %}
**SMART** (от англ. specific, measurable, achievable, relevant, time bound — конкретика, измеримость, достижимость, актуальность и ограниченность по времени) — это методика целеполагания, которая помогает объединить желания, потребности и возможности в конкретную, достижимую цель.
{% endhint %}

### S – Specific (Конкретность)&#x20;

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

### M – Measurable (Измеримость)

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

Пошаговое выполнение измеримой цели позволяет отследить уже пройденный путь и наглядно увидеть динамику прогресса. Видимый результат — это главная мотивация на пути к достижению цели. А по выполненным этапам можно составить статистику, которая покажет, насколько цель оправдывает потраченные средства.

### A – Achievable (Достижимость)

Частая ловушка планирования — постановка заранее недостижимых задач. Следуя методике, эту ловушку удастся обойти еще на этапе целеполагания.

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

### R – Relevant (Актуальность)&#x20;

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

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

### T – Time bound (С четкими сроками)

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

Источник:&#x20;

* <https://kokoc.com/blog/celi-smart/>


# Матрица Эйзенхауэра

<figure><img src="/files/6ZdhUrqPs20YBDMTdkVG" alt=""><figcaption><p>Матрица Эйзенхауэра</p></figcaption></figure>

## Квадрант А. Важные и срочные дела

Это задачи, выполнение которых должно привести к поставленным целям. Такие задачи нельзя отложить — если не выполнить их вовремя, то негативные последствия наступят раньше, чем задачу получится делегировать.

Задачи из квадрата «Важно и срочно» выполняют в первую очередь и как можно скорее. Их нельзя ни откладывать, ни делегировать — это рискованно.

## **Квадрант В. Важные, но несрочные дела**

Этот квадрат называют «стратегическим», поскольку он напрямую связан с постановкой и достижением целей. Сюда попадают задачи по саморазвитию и повседневная работа над важными проектами.&#x20;

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

## Квадрант С. Срочные, но неважные дела

Сюда попадают срочные дела, которые не имеют отношения к главным целям.

Любой ценой сокращать время на выполнение этих задач. Дела из квадрата «Срочно, но не важно» следует делегировать или автоматизировать.

## Квадрант D. Неважные и несрочные дела

Сюда попадают задачи, которые не имеют ни ценности, ни дедлайнов и не стоят внимания.

Задачи из квадрата «Не важно и не срочно» выполняют по остаточному принципу (после завершения основной работы) или не делают совсем.

Источники:

* <https://practicum.yandex.ru/blog/matritsa-eizenhauera/>
* <https://singularity-app.ru/blog/matritsa-eyzenkhauera-podrobnoe-rukovodstvo/>


# RICE

{% hint style="info" %}
**RICE** – это аббревиатура четырех факторов, которая используется для оценки задач проекта: Reach, Impact, Confidence и Effort.
{% endhint %}

### R – Reach (Охват)&#x20;

Оценивает, сколько пользователей или клиентов затронет данная задача или гипотеза. Чем больше людей она затронет, тем выше оценка.

Для оценки, используют количество клиентов, например, в тысячах.&#x20;

### I – Impact (Влияние)

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

Для оценки, используют параметры:

* 3 — массовое влияние
* 2 — высокое
* 1 — среднее
* 0.5 — низкое
* 0.25 — минимальное

### C – Confidence (Уверенность)

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

* 1 — высокая уверенность
* 0.8 — средняя
* 0.5 — низкая

### E – Effort (Усилия)

Оценивает затраты, необходимые для выполнения. Измеряется в человека-месяцах.

Если на реализацию нужна 1 неделя — пишем 0.25 (1/4 месяца). Нужно делать 6 месяцев — пишем 6.

## RICE Score

$$
Score = \frac{R \* I \* C}{E}
$$

Чем выше RICE Score, тем ценней задача, а значит имеет больший приоритет.

Источник:

* <https://vc.ru/life/702812-prioritezaciya-gipotez-i-zadach-s-pomoshyu-rice>


# HADI

Почитать:

* <https://habr.com/ru/articles/716912/>


# Требования

## Вопросы на которые ответим:

* Что такое требование к ПО?
  * Какие группы/виды требований бывают?
  * Чем отличаются бизнес-требования от функциональных?
  * Чем отличаются функциональные требования от нефункциональных? &#x20;
    * Что входит в функциональные требования?&#x20;
    * Что входит в нефункциональные требования?
  * (\*) Привести пример функциональных, нефункциональных и пользовательских требований.&#x20;
  * Приходилось ли вам писать пользовательские истории User story? Приведите шаблон, по которому они составляются и пару произвольных примеров.
  * Приходилось ли вам писать варианты использования Use cases? Как их оформлять и какие шаблоны вы знаете?
* Каким критериям качества должны соответствовать требования? Приведите пример требования, которое удовлетворяет всем качествам.
  * Что содержится в вашей типовой постановке задач для разработчика?
  * Насколько детально вы описываете то, что требуется реализовать? Бизнесовым или техническим языком?
* Заинтересованные лица (стейкхолдеры) - кто это и как с ними взаимодействовать?
  * Какими инструментами для фиксирования требований вы пользовались? Какие в принципе существуют?
  * (\*) Как управлять требованиями? Что делать, если релиз уже распланирован и тут бизнес-заказчик прибегает с горящими глазами и требует внести срочную доработку в текущий релиз. Как бы вы отработали эту ситуацию? (ближе к Бизнес-аналитику)


# Классификация требований

> "Я думаю о требованиях, как о свойствах, которыми должен обладать продукт, чтобы представлять какую-то ценность для пользователей"\
> \
> Карл И. Вигерс

***

{% hint style="info" %}
**Требования к ПО** — это спецификация того, что должно быть реализовано. В них описано поведение системы, свойства системы или ее атрибуты. Требования могут служить ограничениями в процессе разработки системы.
{% endhint %}

<figure><img src="/files/p2GOHfd4NXPA7m3cxVqv" alt=""><figcaption><p>Схема требований</p></figcaption></figure>


# Уровень: Бизнес

бизнес диктует правила игры

## Бизнес-требования

**Бизнес-требования (business requirements)** - это высокоуровневая цель организации или заказчиков системы. Как правило, их высказывают те, кто финансируют проект, покупатели системы, менеджер реальных пользователей, отдел маркетинга.

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

Бизнес-требования — это верхний уровень абстракции требований к системе. Они не относятся напрямую к реализации проекта, а в первую очередь отражают цели бизнеса, абстрагированные от реализации системы. В конечном итоге бизнес-требования формируют документ концепции и границ.

Если кратко, документ содержит определение следующих понятий:

* Бизнес-возможности, бизнес-проблемы — факты и события, формирующие бизнес-цели, то есть грубо — причины инициации проекта.
* Бизнес-цели — цели, которые должны быть решены разработкой и вводом в эксплуатацию системы. Являются критериями успеха проекта.
* Концепция продукта (Vision) — сжато описывает конечный продукт, который достигнет заданных бизнес-целей.
* Границы проекта (scope) — показывают, на какую часть конечной концепции продукта будет направлен текущий проект или итерация.

### Пример

* Сократить время обработки заказа на 50% (цель) — система должна предоставить интерфейс, упрощающий создание заказа (концепция).
* Увеличить клиентскую конверсию до 35% (цель) — в системе должны быть представлены механизмы побуждения клиента к заказу (концепция).

## Бизнес-правила

**Бизнес-правила** (business rules) включают корпоративные политики, правительственные постановления, отраслевые стандарты и вычислительные алгоритмы. Сами бизнес-правила не являются требованиями к ПО, потому что они находятся за пределами любой системы ПО. Однако они часто налагают ограничения, определяя, какими функциями должна обладать система, подчиняющаяся соответствующим правилам.&#x20;

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

### Пример

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

Источник: <https://tproger.ru/articles/vyjavlenie-i-sbor-trebovanij-k-po-ultimate-guide>


# Уровень: Пользователь

## Пользовательские требования

**Пользовательские требования (user requirements)** описывают цели или задачи, которые пользователи должны иметь возможность выполнять с помощью продукта, который в свою очередь должен приносить пользу кому-то. Область пользовательских требований также включает описания атрибутов или характеристик продукта, которые важны для удовлетворения пользователя.&#x20;

Пользовательские требования также часто именуются фичами.

**Фича (функциональность)** — функционально обобщенные части системы, решающие отдельные задачи пользователей или интерпретирующие бизнес-процессы (и их артефакты), которые будут реализованы в рамках системы.

Исходя из вышеописанных определений, пользовательские требования содержат:

* Цели и задачи пользователей
* Сценарии использования — способ решения задачи пользователей
* Как следствие, описание самих пользователей системы
  * пользовательские роли
  * уровни доступа.

В конечном итоге пользовательские требования формируют «Документ пользовательских требований». Пользовательские требования могут быть представлены в виде:

* текстового описания
* вариантов использования, сценариев использования (Use Case)
* пользовательских историй (User Story)
* диаграммы вариантов использования

### Пример

* Пользователь должен иметь возможность добавить объект в избранное (функциональность).

Источник: <https://tproger.ru/articles/vyjavlenie-i-sbor-trebovanij-k-po-ultimate-guide>


# Use case

ЧТО система должна сделать, чтобы актор достиг цели

{% hint style="info" %}
**Use case** представляет собой детальное описание взаимодействия между актерами (пользователями) и системой. Он описывает конкретную ситуацию, в которой актер взаимодействует с системой для достижения определенной цели.&#x20;
{% endhint %}

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

## Алгоритм описания Use case (UC)

Типовую последовательность разработки функциональных требований в форме UC можно представить следующим образом:

1. Определить **Акторов** — тех, кто взаимодействует с системой
2. Выявить и составить **список** UC — задач, которые стейкхолдеры смогут решить с помощью системы
3. Для каждого юскейса определить **приоритет** — важность UC по отношению к другим вариантам использования
4. Для каждого важного юскейса определить **контекст** применения, конечную **цель и результат**
5. Описать **основной поток** каждого UC с высоким приоритетом в виде последовательности шагов, которая приведёт к достижению его цели — пользовательского сценария (use case scenario)
6. Дополнить основной поток **расширениями**, **исключениями и циклами**
7. Собрать **воедино** результаты шагов 4−6, детально описав каждый юскейс с высоким приоритетом как алгоритм взаимодействия пользователя с системой

Теперь давайте рассмотрим каждый шаг поподробнее.

### Шаг 1. Определить **Акторов**

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

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

### Шаг 2. Составить список UC

Мы советуем делать это в виде **реестра юскейсов** — единой таблицы, показывающей распределение юскейсов по акторам.\
\
Рекомендуем называть UC в формате «Инфинитив + Объект», где «Инфинитив» — это инфинитив глагол в совершенного вида с большой буквы, а «Объект» — это существительное, обозначающее объект управления с большой буквы.\
\
Из названия варианта использования должно быть сразу понятно, какую именно задачу пользователя он решает. Например, «Подписать Документ», «Оформить Заказ», «Оплатить Товар», «Сделать Звонок» и так далее. Для повышения наглядности можно сделать это в табличном виде или UML-диаграммы вариантов использования (она же Use case diagram, диаграмма прецедентов).

### Шаг 3. Определить приоритет

Реализация юскейсов в коде — трудоёмкая работа, поэтому надо понимать, с каких лучше начать в первую очередь, а до каких очередь может не дойти никогда.\
\
Реестр юскейсов может использоваться для приоритизации пользовательских функциональных требований с целью их ранжирования по степени важности, которая определяет порядок реализации.\
\
Самым простым методом приоритизации, который часто применяется на практике, считается метод MoSCoW.&#x20;

<details>

<summary>MoSCoW</summary>

* ***Must*** — то, что необходимо сделать в любом случае. Считается, что без реализации этих требований решение не будет работать или при отсутствии этих фич продукт не будет нужен потребителям. Чаще всего этот приоритет называется 1-я очередь и обозначается цифрой 1
* ***Should*** — требования 2-ой очереди, которые должны быть реализованы после тех, что отнесены к группе Must. Это приоритет номер 2
* ***Could*** — желательные требования, которые можно сделать, если останется время и будут ресурсы. Это приоритет номер 3
* ***Would*** — требования, которые хотелось бы реализовать, но пока их можно проигнорировать или перенести на следующие итерации без вреда для продукта. Это приоритет номер 4

</details>

### Шаг 4. Определить контекст/цель/результат для Must have

Контекст = описание проблематики

Цель = итог Use Case

Результат = постусловия

### Шаг 5. Описать основной поток для Must have

**Пользовательский сценарий** — это последовательность шагов, которая приведёт к достижению конечной цели юскейса, получению нужного актору результата.

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

### Шаг 6. Дополнить основной поток **расширениями**, **исключениями и циклами**

На этом этапе аналитик усложняет ранее полученный happy path, включая в схему различные ветвления с помощью логического оператора XOR.

### Шаг 7. **Собрать воедино результаты выполнения трёх предыдущих шагов, детально описав каждый UC как алгоритм взаимодействия пользователя с системой**

На этом этапе у каждого юскейса появляется описание, структура которого всегда примерно такая:

* Имя
* Приоритет
* Область действия
* Контекст
* Актор
* Цель
* Предусловия
* Результат (постусловие)
* Основной поток
* Расширения или альтернативные потоки
* Бизнес-правила

## Преимущества UC

* Нисходящая и восходящая трассировка (от системного уровня к бизнесу) улучшает понятность требований для Заказчика и команды реализации: UC несёт конечную бизнес-ценность, детально описывает структуры данных и бизнес-логику их обработки, позволяет убедиться в реализации
* Вариант использования можно использовать как единицу поставки при планировании, реализации, тестировании и приёмке работ
* Набор связанных друг с другом вариантов использования позволяет обеспечить полноту функциональных требований, следующих из потребностей пользователей
* Детальный шаблон представления UC позволяет полностью описать взаимодействие актора с системой, включая контекст, предшествующие, сопутствующие и результирующие события, а также ссылки к бизнес-правилам и нефункциональным требованиям (ограничения и некоторые атрибуты качества)
* UC — отличная база для формирования тестовых сценариев (test cases) для проверки того, работает ли реализованная система как ожидалось

## Недостатки UC

* Плохо подходят для документирования требований, основанных не на взаимодействии с системой, а на выполнении расчётов и преобразованиях уже имеющихся в системе данных. Например, построение графиков и отчётов, вычисления, описание математических алгоритмов
* Субъективность: качество изложения как самого UC, так и их реестра (ширина, глубина детализации уровней абстракции) зависит от навыков аналитика
* На детальную проработку каждого UC уходит много времени
* Проектирование системы только по UC исключает другие потенциально ценные методики документирования и анализа требований, такие как каноническая форма представления функциональных требований с привязкой с CRUD-операциям или популярная в Agile-проектах форма User Story по INVEST с критериям приёмки (Acceptance Criteria)

Источник: <https://systems.education/functional_requirements_in_usecases>


# User story

{% hint style="info" %}
**User stories** представляют собой короткие, простые и понятные описания функциональности системы с точки зрения конечного пользователя или заинтересованной стороны. Они фокусируются на описании потребностей и целей пользователей, а не на технических деталях. Каждая user story содержит название, описание и критерии приемки.&#x20;
{% endhint %}

## Формат записи User story

Я, как \[Роль пользователя]\
Хочу \[решить задачу/выполнение какого-либо действия]\
Когда \[при каких условиях/обстоятельствах]\
Чтобы \[достичь цель]

### Пример

Я, как \[юзер кофе-машины] \
Xочу \[взбить молоко] \
Когда \[открываю кран подачи пара] \
Чтобы \[получилась густая молочная пенка]

Я, как \[юзер кофе-машины]\
хочу \[иметь возможность наливать воду в кофе-машину]\
Когда \[открываю крышку резервуара с водой]\
Чтобы \[кофе-машина могла функционировать]

## INVEST

Написанную User Story можно оценить по шести критериям INVEST, которые сформулировал консультант и директор по развитию продукта Билл Уэйк.

* **Independent** (независимый). В пользовательской истории лучше описывать одну или несколько независимых функций. Они должны решить проблему пользователя без помощи других инструментов.&#x20;
* **Negotiable** (подлежащий обсуждению). User Story обязательно нужно обсудить в команде и внести изменения, если потребуется. Без обсуждения есть риск, что команда разработки получит неполное представление о задаче.
* **Valuable** (ценный). В функции, которую описывает User Story, должна быть реальная ценность для пользователя.
* **Estimable** (поддающийся оценке). Хорошую User Story можно оценить — понять, сколько времени, ресурсов и денег займёт разработка функции.
* **Small** (маленький). История должна быть краткой и ёмкой. Объёмные истории сложнее оценить, и они могут потребовать больше ресурсов на разработку.
* **Testable** (поддающийся тестированию). С критериями приёмки команде разработки будет проще создать нужную функцию. Тестировать историю лучше за один раз — это ещё одна причина, почему в истории не должно быть много деталей.

Источники:&#x20;

* <https://habr.com/ru/companies/deutschetelekomitsolutions/articles/598625/> (почитать)
* <https://practicum.yandex.ru/blog/chto-takoe-user-story-i-kak-napisat/>


# Job story

альтернатива User story

{% hint style="info" %}
User Story описывают функциональность продукта с точки зрения пользователя, а Job Story — выявляют одинаковые мотивы поведения разных людей в конкретных ситуациях.
{% endhint %}

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

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

## User story vs Job story

<figure><img src="/files/oaDwzLmfiOIO2OrD8y3g" alt="" width="525"><figcaption><p>Концепция User story</p></figcaption></figure>

<figure><img src="/files/LdcHvUzXNfkcDbPbJbpq" alt="" width="524"><figcaption><p>Концепция Job Story</p></figcaption></figure>

## Формат записи Job story

Когда \[ситуация],\
я хочу \[мотивация],\
чтобы \[ожидаемый результат].

**Job Story состоит из трех частей:**

1. **Контекст** — описание ситуации, в которой у человека возникает затруднение или проблема.
2. **Мотивация** — что должно произойти, чтобы человек избавился от проблемы? Здесь описывается как человек видит себе решение проблемы, а не то, что вы хотите от него добиться. Это не конкретный продукт и не фичи.
3. **Желаемый прогресс** — почему или для чего человек хочет решить проблему? Когда человек найдет решение проблемы, как улучшится его жизнь? Какие возможности у него появятся, которых не было раньше, если проблема решиться?

## Пример

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

Когда \[я переехал в незнакомый город или страну], \
я хочу \[завести рабочие знакомства с интересными людьми], \
чтобы \["забустить" свой бизнес].

Когда \[пытаюсь найти ВУЗ, но тону в море информации об учебных заведениях и факультетах из разных источников], \
я хочу \[сопоставить свои возможности (предметы, баллы, бюджет) и предложение на рынке образования (учебные заведения, специальности)], \
чтобы \[не пропустить неочевидную возможность].

Источники:&#x20;

* <https://vc.ru/productstar/148852-kak-job-stories-pomogut-v-sozdanii-krutogo-interfeysa>
* <https://habr.com/ru/companies/friifond/articles/260457/>
* <https://glubina.studio/blog/gajd-po-job-stories>


# Уровень: Продукт

Поговорим про главные требования предъявляемые на уровне продукта, а именно про функциональные и нефункциональные требования.&#x20;


# Функциональные требования

количественные характеристики (что?)

{% hint style="info" %}
**Функциональные требования** (functional requirements) определяют, каким должно быть поведение продукта в тех или иных условиях. Они определяют, что разработчики должны создать, чтобы пользователи смогли выполнить свои задачи (пользовательские требования) в рамках бизнес-требований. Такое соотношение между тремя уровнями требований жизненно важно для успеха проекта.

Пример:

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

{% endhint %}

<figure><img src="/files/vfP7IIRzfGgWQs4iO7kU" alt="" width="563"><figcaption><p>Функциональные требования</p></figcaption></figure>

## Системные требования

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

Однако, в практике многих компаний термин «системные требования» часто применяется для обозначения требований третьего уровня. Большинство специалистов понимают, что такое бизнес-требования и пользовательские требования. Но когда речь идет о третьем уровне, мнения расходятся. Я предпочитаю использовать термин «требования к реализации», Вигерс же предлагает «функциональные требования». В то же время, некоторые компании используют для этого уровня термин «системные требования».

В контексте терминологии Вигерса, системные требования можно проиллюстрировать на следующем примере. Допустим, у нас есть интернет-банк, и требуется, чтобы доступ к операциям со счетом осуществлялся через единый сервер приложений. С этим сервером могут взаимодействовать различные клиентские приложения: интернет-банк в браузере пользователя, мобильное приложение или отдельное Java-приложение на компьютере пользователя. Это требование описывает систему в целом, и дает нам понимание, что есть несколько вариантов клиентской части приложения, но все они должны работать с единым сервером.

Источник: <https://www.webursitet.ru/article/vidy-trebovanii-k-programmnomu-produktu.html>


# Нефункциональные требования

качественные характеристики (как?)

{% hint style="info" %}
**Нефункциональные требования**: содержит подробную информацию о том, как должна работать система. Например, производительность, возможности, масштабируемость, безопасность и т. д. Нефункциональные требования говорят о качественных характеристиках и атрибутах систем.
{% endhint %}

Нефункциональные требования складываются из трех частей:

<figure><img src="/files/ekF8LoqI7PxM6NUZbZMH" alt="" width="563"><figcaption><p>Нефункциональные требования</p></figcaption></figure>

## Атрибуты качества

**Атрибуты качества (quality attributes)** представляют собой дополнительное описание функций продукта, выраженное через описание его характеристик, важных для пользователей или разработчиков.&#x20;

Например, к таким характеристикам относятся:

* легкость и простота использования (usability)
* производительность (performance)
* удобство эксплуатации и технического обслуживания (maintainability)
* надежность и устойчивость к сбоям (reliability)
* взаимодействия системы с внешним миром (interfaces)
* расширяемость/масштабируемость (scalability)

<details>

<summary><span data-gb-custom-inline data-tag="emoji" data-code="1f4ce">📎</span> FRUPS</summary>

К требованиям атрибутов качества ПО относят требования FURPS или FURPS+. Эта модель требований  представлена Грейди и Касуэлл, работающими в тот момент времени в компании Hewlett-Packard.

FURPS это пять тезисов:

* **Функциональность** (Functionality). Какие функции должны быть в системе.&#x20;
* **Устойчивость к отказам** (Reliability). Устойчивость к отказам.&#x20;
* **Удобство использования** (Usability). Удобство работы пользователей.&#x20;
* **Производительность** (Performance). Скорость, эффективность, потребление ресурсов, пропускная способность, время отклика.
* **Сопровождаемость** (Supportability). Все вместе: Тестируемость, расширяемость, адаптируемость, ремонтопригодность, совместимость, настраиваемость, удобство обслуживания, локализуемость, портативность.

</details>

### Примеры

* Время загрузки главной страницы и карточки товара не должно превышать 3 секунды при нагрузке до 20 посетителей в минуту
* База данных сайта должна устанавливаться на сервера MySQL, MS SQL Server или Oracle без необходимости внемения изменений в установочные скрипты
* Сайт должен быть адаптирован для мобильных устройств

## Ограничения

**Ограничения (constraints)** касаются выбора возможности разработки внешнего вида и структуры продукта.

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

### Примеры

Например, "Требуется ограничить загрузку файлов размером более 20мб", "Ограничить работу приложения только на IOS" или только в браузере Chrome и т.д.

Возьмем в качестве примера следующее ограничение: сервер приложений сайта должен разрабатываться на языке Java. Почему такое требование может быть предъявлено? Возможно, потому что у заказчика имеется большое количество специалистов, способных сопровождать работу системы, написанной на этом языке, а все остальные серверы приложений заказчика также функционируют в этой среде.

Другой похожий пример: сайт должен устанавливаться на определенную версию операционной системы.

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

## Внешний интерфейс

**Внешние интерфейсы** - описание аспектов взаимодействия с другими системами и операционной средой. К ним относятся требования к API продукта или системы, а также требования к API других систем, с которыми осуществляется интеграция.

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

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

### Примеры

Вот несколько примеров внешних интерфейсов:

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

Источники:&#x20;

* <https://foranalysts.blogspot.com/2011/08/blog-post_17.html>
* [https://analytics.infozone.pro/requirements-analysis/analysis-of-requirements-wiegers-2004](https://analytics.infozone.pro/requirements-analysis/analysis-of-requirements-wiegers-2004/)
* <https://www.webursitet.ru/article/vidy-trebovanii-k-programmnomu-produktu.html>
* [pikabu.ru/story/karera\_v\_it\_sistemnyiy\_analitik\_chast\_1\_vidyi\_i\_kachestva\_trebovaniy\_9945259](https://pikabu.ru/story/karera_v_it_sistemnyiy_analitik_chast_1_vidyi_i_kachestva_trebovaniy_9945259)
* <http://foranalysts.blogspot.com/2011/08/blog-post_3440.html>


# Качества требований

{% hint style="info" %}
Обязательные качества отмечены **(!)**.
{% endhint %}

* **Атомарность** - требование является атомарным, если его нельзя декомпозировать на несколько требований.
* **Завершенность и полнота** - требование содержит полный набор информации для однозначного понимания.
* **Краткость** - чем лаконичнее требование, тем лучше.
* **(!) Консистентность** - требование не должно противоречить самому себе и другим требованиям.
* **(!) Выполнимость** - требование возможно реализовать в рамках проекта (его сроков и бюджета).
* **Проверяемость** - реализованность требования может быть определена через один из четырёх возможных методов: осмотр, демонстрация, тест или анализ.
* **(!) Однозначность** - разработчик, тестировщик (или любой другой человек) должен понять это требование также, как и вы. Соответственно требование не должно быть расплывчато, размыто, не должно содержать непонятных аббревиатур.

<details>

<summary><span data-gb-custom-inline data-tag="emoji" data-code="1f4ce">📎</span> Some fun</summary>

[История ](https://www.youtube.com/watch?v=8BctbPxfVQ8)о том, какими не должны быть требования.

</details>


# Методы сбора требований

Существует несколько методов сбора требований, которые могут быть использованы для сбора информации и выявления требований у заинтересованных сторон (стейкхолдеров). Вот некоторые из распространенных методов:

1. **Интервью:** Проведение интервью с заинтересованными сторонами является одним из основных методов сбора требований. В ходе интервью задаются вопросы и проводится обсуждение с целью получения информации о требованиях, целях, ограничениях и ожиданиях относительно системы.
2. **Наблюдение:** Наблюдение за деятельностью пользователей или процессами бизнеса может быть полезным методом для сбора требований. Наблюдение позволяет получить информацию о реальных действиях и проблемах пользователей, которые могут быть использованы для выявления требований.
3. **Фокус-группы:** Фокус-группы представляют собой групповые дискуссии с представителями различных заинтересованных сторон. Этот метод позволяет собрать мнения, идеи и требования от разных людей в структурированной форме.
4. **Прототипирование:** Прототипирование — создание пробных версий системы или ее компонентов, которые могут быть показаны заинтересованным сторонам для сбора обратной связи и выявления требований. Прототипирование позволяет лучше понять потребности пользователей и вносить корректировки в требования на ранних стадиях.
5. **Работа в группе:** Совместные рабочие сессии и мозговые штурмы в группе могут помочь в сборе требований. В этих сессиях заинтересованные стороны совместно работают над определением требований, обсуждают их и принимают решения.
6. **Анализ документов:** Анализ существующих документов, таких как бизнес-планы, отчеты, контракты, может предоставить ценную информацию о требованиях и контексте системы.

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

Источник: <https://testengineer.ru/requirements-gathering/>


# Техническое задание (ТЗ)

Агрегируя набор требований к решению с кратким описанием контекста его практического использования, ТЗ является базисом для Заказчика и команды реализации (разработчиков, тестировщиков, руководителя проекта). Поэтому можно сказать, что работа аналитика считается успешно выполненной, если написано хорошее ТЗ, по которому у разработчиков не возникает вопросов.&#x20;

Считаем, что все требования были собраны. Тогда, написание ТЗ будет состоять из следующих шагов:

* Определить границы ТЗ (scope)
* В случае, если в компании есть шаблон ТЗ, использовать его
* Прописать [user story](/soft-skills/trebovaniya/klassifikaciya-trebovanii/uroven-polzovatel/user-story) / [use case](/soft-skills/trebovaniya/klassifikaciya-trebovanii/uroven-polzovatel/use-case)
* Добавить описание [интеграционных сервисов](/hard-skills/integracii)
* Добавить [диаграммы бизнес-процессов](/hard-skills/proektirovanie/notacii-i-diagrammy)
  * AS IS - как система работает сейчас&#x20;
  * TO BE - как система должна работать
* При необходимости, добавить [макеты](/hard-skills/proektirovanie/prototipirovanie), полученные от дизайнера
* При необходимости, добавить информацию про [логирование / мониторинг](/hard-skills/proektirovanie/monitoring)
* Оформить ТЗ в итоговый документ. Обычно для этого используется:
  * Confluence
  * Word or etc.

<figure><img src="/files/kA2FYJvcAlo0PeOsYUop" alt=""><figcaption><p>Чего нужно постараться избежать</p></figcaption></figure>


# Базы данных

## Вопросы на которые ответим:

* Какие виды БД бывают?
  * Где и когда применяются реляционные БД?
  * Какие типы нереляционных БД бывают?
* Какие требования предъявляются к реляционным БД?&#x20;
  * Что такое транзакция?
  * Какими свойствами должна обладать транзакция? (ACID)
* Что такое первичный ключ? Каким свойством обладает первичный ключ? Что такое внешний ключ?
* Знакомы ли вы с нормализацией баз данных?
  * Можете назвать три первые формы нормализации?
  * (\*) Задача на нормализацию таблиц базы данных. Дают две таблицы с некоторыми полями. Что в них не так и почему? Как исправить?
* Какие типы данных в БД бывают?
* Какие операторы используются в SQL?
  * Приходилось ли вам писать SQL-запросы? Для чего?
  * Какие виды соединений таблиц вы знаете? Чем они отличаются?
  * Задача SQL. Дают таблицы. Напишите SELECT с такими-то условиями запроса.
  * Задача SQL. Дается SQL запрос. Назовите все ошибки в синтаксисе, которые вы видите.
  * Чем отличается UNION от UNION ALL?
  * (\*) Чем TRANCATE отличается от DELETE?
  * (\*) Задача SQL. Даются следующие три операции SQL. Какой будет результат?

```
BEGIN TRANSACTION;
TRUNCATE TABLE;
ROLLBACK;
SELECT * FROM TABLE;
```

* (\*) Зачем нужны индексы в таблицах БД?
* (\*) Какие бывают представления в БД?


# Реляционные

{% hint style="info" %}
**Реляционная база данных** (англ. *relation* — отсюда и название модели) — это составленная по реляционной модели база данных, в которой данные, занесенные в таблицы, имеют изначально заданные отношения. Сами таблицы в такой базе данных также соотносятся друг с другом строго определенным образом. Реляционные базы данных используют целый комплекс инструментов, которые обеспечивают целостность данных, т. е. их точность, полноту и единообразие.
{% endhint %}

## **Транзакция. ACID.**

**Транзакция** — это комплекс последовательных операций с применением операторов SQL, имеющих определенную цель. Все транзакции должны отвечать четырем требованиям ACID:

* **Атомарность** (англ. *atomicity*) — транзакция является неделимым блоком и выполняется или полностью, или никак.
* **Согласованность** (англ. *consistency*) — завершенная транзакция сохраняет согласованность базы данных.
* **Изолированность** (англ. *isolation*) — параллельные транзакции не могут влиять друг на друга.
* **Устойчивость** (англ. *durability*) — никакой сбой в системе не может влиять на результат завершенной транзакции.

Подробнее в главе:

{% content-ref url="/pages/YczbaXjP9GEPVNFh3Pje" %}
[Транзакции](/hard-skills/bazy-dannykh/relyacionnye/tranzakcii)
{% endcontent-ref %}

## SQL

Для взаимодействия с любой реляционной базой данных используется SQL (Structured Query Language) — язык структурированных запросов. Это основа интерфейса систем управления базами данных. Он стандартизирован с 1986 года и поддерживается всеми известными ядрами реляционных баз данных. SQL позволяет работать со строками таблиц, а также извлекать нужные блоки информации и производить транзакции.

Подробнее в главе:

{% content-ref url="/pages/EplcpL7XCoLgWFNF59em" %}
[SQL](/hard-skills/bazy-dannykh/relyacionnye/sql)
{% endcontent-ref %}

## Констрейты <a href="#parameters" id="parameters"></a>

* NOT NULL
* UNIQUE
* CHECK
* DEFAULT
* PRIMARY KEY (ПК, Первичный ключ)
* FOREIGN KEY (ВК, Внешний ключ)

Подробнее в главе:

{% content-ref url="/pages/rtXyedbaGeIO7HnA5ork" %}
[Констрейты](/hard-skills/bazy-dannykh/relyacionnye/konstreity)
{% endcontent-ref %}

## Основные характеристики реляционных баз данных <a href="#parameters" id="parameters"></a>

| Признак                                    | Пояснение                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Множество сущностей**                    | Объекты со строго определенным набором атрибутов, с помощью которых они связываются между собой, формируют понятную и простую для восприятия структуру.                                                                                                                                                                                 |
| **Табличный формат**                       | Такой формат гарантирует высокий уровень структурированности с жесткими логическими взаимосвязями, минимальный уровень избыточности данных, их согласованность и целостность.                                                                                                                                                           |
| **Язык SQL**                               | SQL является стандартизированным средством общения пользователя с базой данных. Он очень формальный, что делает его удобным и простым в изучении. SQL гарантирует точный результат даже при сложном многоуровневом запросе.                                                                                                             |
| **Масштабирование по вертикали**           | Реляционные базы данных хорошо масштабируются по вертикали. Но это значит, что по мере накопления информации в какой-то момент ее обработка потребует больших аппаратных ресурсов и финансовых затрат.                                                                                                                                  |
| **Масштабирование по горизонтали**         | Горизонтальное масштабирование, подразумевающее распределение таблиц данных по множеству серверов, является слабой стороной реляционных баз данных. С разрастанием системы появляются задержки в обновлении данных. В какие-то моменты нарушается принцип целостности данных, что может негативно отразиться на пользовательском опыте. |
| **Наличие требований к параметрам данных** | Реляционные базы данных умеют работать только со структурированными данными. Но современный цифровой мир полон неструктурированных данных (например, фото и видео), к которым нельзя применять принципы реляционной модели.                                                                                                             |

## Примеры

### MySQL

Это открытая СУБД, купленная Oracle. С ней работают (41,09%) всех разработчиков (по [результатам](https://survey.stackoverflow.co/2023/#section-most-popular-technologies-databases) опроса, который в 2023 году провёл сайт StackOverflow\.com).

Главные её преимущества — бесплатность и высокая скорость работы с данными. MySQL создавалась для обработки огромных массивов информации в промышленных масштабах, но благодаря доступности и быстродействию оккупировала Всемирную паутину, заслужив звание «СУБД всея интернета». И сегодня MySQL всё ещё самая удобная СУБД для работы с интернет-страницами и веб-приложениями.

### SQLite

Основным ее достоинством считается встраиваемость, которая обусловлена тем, что SQlight в отличие от остальных СУБД является не приложением на подобие «клиент-сервер», а подключаемой библиотекой.

### PostgreSQL

Её можно назвать самой продвинутой. Это не просто реляционная, а объектно-реляционная свободная СУБД.

PostgreSQL поддерживает не только типы данных, которые есть в других реляционных СУБД. Помимо числовых, текстовых, булевых и других стандартных типов, в ней можно хранить и обрабатывать геометрические и денежные данные, сетевые адреса, JSON, XML, массивы, а также создавать собственные типы данных.

Источники:

* <https://cloud.yandex.ru/docs/glossary/relational-databases>
* <https://skillbox.ru/media/code/sql_i_nosql_in_i_yan_v_mire_baz_dannykh>


# Транзакции

{% hint style="info" %}
**Транзакция** — это набор действий с данными, объединенный в логическую единицу. Она либо выполняется целиком, либо нет.
{% endhint %}

## Проблемы неизолированных транзакций <a href="#id-2" id="id-2"></a>

* **Потерянное обновление**

Когда две транзакции записывают разные значения в одну и ту же ячейку, одно из изменений теряется.

* **Грязное чтение**

Когда читаются данные, которые в этот момент изменяются транзакцией, а потом транзакция откатывается и данные исчезают.

* **Неповторяющееся чтение**

Когда несколько раз читаются данные, которые в этот момент изменяются транзакцией — каждый раз данные могут отказаться другими.

* **Фантомное чтение**

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

## Изоляция транзакций <a href="#id-2" id="id-2"></a>

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

* **Чтение неподтверждённых данных (read uncommitted)**

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

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

* **Чтение подтверждённых данных (read committed)**

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

* **Повторяемое чтение (repeatable read)**

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

* **Сериализуемый (serializable)**

Транзакции полностью изолируются друг от друга, каждая выполняется так, как будто параллельных транзакций не существует.

## ACID

Это набор из четырех требований к транзакционной системе, обеспечивающих максимально надежную и предсказуемую работу. Не все базы данных полностью реализуют ACID.

### Атомарность (atomicity)

Атомарность гарантирует, что каждая транзакция будет выполнена полностью или не будет выполнена совсем. Не допускаются промежуточные состояния.

### Согласованность (consistency)

Согласованность — это требование, подразумевающее, что в результате работы транзакции данные будут допустимыми. Это вопрос не технологии, а бизнес-логики: например, если количество денег на счете не может быть отрицательным, логика транзакции должна проверять, не выйдет ли в результате отрицательных значений.

### Изолированность (isolation)

Гарантия того, что параллельные транзакции не будут оказывать влияния на результат других транзакций. Мы разобрались с изоляцией выше.

### Долговечность (durability)

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

Источники:

* <https://www.flenov.info/books/read/free-sql-book/116>
* <https://gb.ru/blog/acid-cap-transactions/>


# CAP


# Нормальные формы

{% hint style="info" %}
**Нормальная форма (НФ)** — требование, предъявляемое к структуре таблиц в теории реляционных баз данных для устранения из базы избыточных функциональных зависимостей между атрибутами (полями таблиц).
{% endhint %}

Всего существует 6 нормальных форм, однако зачастую на практике применяют только первые 3.

* 1НФ
* 2НФ
* 3НФ
* Нормальная форма Бойса-Кодда (частный случай 3НФ)
* 4НФ
* 5НФ
* 6НФ

{% hint style="success" %}
Важно отметить, что данные формы должны соблюдаться последовательно, то есть таблицы не могут находится в 2НФ не находясь при этом в 1НФ.
{% endhint %}

## 1 Нормальная форма

Отношение находится в 1НФ, если все его атрибуты являются простыми, все используемые домены должны содержать только скалярные значения. Не должно быть повторений строк в таблице.

* Одно поле = одно значнеие
* Нет повторов строк

## 2 Нормальная форма

Отношение находится во 2НФ, если оно находится в 1НФ и каждый не ключевой атрибут неприводимо зависит от Первичного Ключа(ПК).

* Если есть такая возможность вынести часть таблицы через ПК/ВК - это нужно сделать

## 3 Нормальная форма

Отношение находится в 3НФ, когда находится во 2НФ и каждый не ключевой атрибут нетранзитивно зависит от первичного ключа. Проще говоря, второе правило требует выносить все не ключевые поля, содержимое которых может относиться к нескольким записям таблицы в отдельные таблицы.

* То же самое, что и в 2 НФ, но сохраняя логику отношений таблиц&#x20;


# SQL

{% hint style="info" %}
**SQL** — язык структурированных запросов (SQL, Structured Query Language), который используется в качестве эффективного способа сохранения данных, поиска их частей, обновления, извлечения и удаления из базы данных.
{% endhint %}

Обращение к реляционным СУБД осуществляется именно благодаря SQL. С помощью него выполняются все основные манипуляции с базами данных, например:

* Извлекать данные из базы данных
* Вставлять записи в базу данных
* Обновлять записи в базе данных
* Удалять записи из базы данных
* Создавать новые базы данных
* Создавать новые таблицы в базе данных
* Создавать хранимые процедуры в базе данных
* Создавать представления в базе данных
* Устанавливать разрешения для таблиц, процедур и представлений

Язык структурированных запросов делится на несколько частей (группы операторов) и позволяет:

* определять данные (DDL[^1]),
* манипулировать ими (DML[^2]),
* контролировать доступ к данным (DCL[^3])
* и управлять транзакциями (TCL[^4]).

Подробнее остановимся на DML-командах с которыми, по большей степени приходиться работать аналитику и вскользь пройдемся по DDL/DCL/TCL-командам.

Полезное: &#x20;

* <https://sql-academy.org/ru/guide/basic-syntax-sql-query>
* <https://sky.pro/media/gruppy-operatorov-sql/>

[^1]: DDL, или Data Definition Language — это группа команд, которые используются для создания и изменения структуры объектов базы данных: таблиц, представлений, схем и индексов.

    Примеры команд: CREATE, ALTER, DROP.

[^2]: DML, или Data Manipulation Language — это группа операторов, которые позволяют получать и изменять записи, присутствующие в таблице.&#x20;

    Примеры команд: SELECT и тд

[^3]: DCL, или Data Control Language — это команды SQL, которые используют для предоставления и отзыва привилегий пользователя базы данных. При этом пользователь не может откатить изменения. &#x20;

    Примеры команд: GRANT и REVOKE

[^4]: TCL, или Transaction Control Language — одни из наиболее популярных команд SQL. Их используют для обеспечения согласованности базы данных и для управления транзакциями. \
    \
    Примеры команд: BEGIN/COMMIT, ROLLBACK


# DML

{% hint style="info" %}
**Data Manipulation Language (DML)** – это группа операторов для манипуляции данными. С помощью этих операторов мы можем добавлять, изменять, удалять и выгружать данные из базы, т.е. манипулировать ими.
{% endhint %}

## SELECT

```sql
// Вывести всю таблицу table
SELECT * FROM table

// Вывести конкретное поле field
SELECT field FROM table

// Вывести уникальные значени поля field
SELECT distinct field FROM table
```

## WHERE

```sql
// Отфильтровать записи по числовому полю
SELECT * FROM table
WHERE field = 123

// Отфильтровать записи по стринг полю
SELECT * FROM table
WHERE field = 'value'


// Отфильтровать записи по вхождению в стринг поле
SELECT * FROM table
WHERE field LIKE 'value'
```

## ORDER BY

```sql
// Отсортировать записи по возрастанию
SELECT * FROM table
ORDER BY field ASC // ACS необязательно, сортировка по умолчанию = по возрастанию

// Отсортировать записи по возрастанию
SELECT * FROM table
ORDER BY field DESC
```

## GROUP BY

```sql
// Группировка по полю field 
SELECT field FROM table
GROUP BY field
```

## Агрегатные функции

```sql
// AVG
// Среднее значение по полю field
SELECT AVG(field) FROM table
// Среднее значение по полю field, группируя по field2
SELECT field2, AVG(field) FROM table
GROUP BY field2

// SUM
// Сумма значений значение по полю field
SELECT SUM(field) FROM table

// MAX
// Максимальное значение по полю field
SELECT MAX(field) FROM table

// MIN
// Минимальное значение по полю field
SELECT MIN(field) FROM table
```

## LIMIT/TOP

```sql
// PostgreSQL и другие
// Вывести топ 10 записей
SELECT * FROM table
LIMIT 10
// Вывести записи с 5 по 10
SELECT * FROM table
LIMIT 5 OFFSET 4

// MS SQL
// Вывести топ 10 записей
SELECT TOP 10 * FROM table
```

## JOIN

{% code fullWidth="true" %}

```sql
//Внутренее соединение 
//Получение данных, относящихся как к левой, так и к правой таблице.
//INNER JOIN или просто JOIN
SELECT * FROM table1 t1
JOIN table2 t2 ON t1.field1 = t2.field1

//Внешнее соединение
//Получение всех данных из левой таблицы, соединённых с соответствующими данными из правой.
//LEFT JOIN
SELECT * FROM table1 t1
LEFT JOIN table2 t2 ON t1.field1 = t2.field1
//Получение всех данных из правой таблицы, соединённых с соответствующими данными из левой.
//RIGHT JOIN
SELECT * FROM table1 t1
RIGHT JOIN table2 t2 ON t1.field1 = t2.field1
//Получение всех данных, относящихся к левой и правой таблицам, а также их внутреннему соединению.
//FULL OUTER JOIN
SELECT * FROM table1 t1
FULL OUTER JOIN table2 t2 ON t1.field1 = t2.field1
```

{% endcode %}

## Подзапросы

```sql
//Пример1
SELECT field1, (SELECT field1 FROM table2) FROM table1
WHERE field1 = 'value'

//Пример2
SELECT field1 FROM table1
WHERE filed1 = (SELECT field2 FROM table2 WHERE field2 = 'value')
```

## UNION

```sql
//Объедение запросов. Без повторов одинаковых строк. 
SELECT * FROM table1
UNION
SELECT * FROM table2

//Объедение запросов. C повторами одинаковых строк. 
SELECT * FROM table1
UNION ALL
SELECT * FROM table2
```

## INSERT/UPDATE/DELETE|TRUNCATE

{% code fullWidth="true" %}

```sql
//Вставить новую запись в таблицу
INSERT INTO table1 (field1, field2)
VALUES ('value_field1', 'value_field2')

//Изменить старую запись в таблице
UPDATE table1
SET field2 = 'value_field2'
WHERE field1 = 'value'

//Удалить конкретную запись в таблице
DELETE FROM table1
WHERE field1 = 'value'
//Удалить все записи в таблице (записи будут удаляться по одной, пока таблица польностью не очистится)
DELETE FROM table1
//Удалить все записи в таблице (удалится вся таблица со всеми записями, после чего создастся новая пустая)
TRUNCATE FROM table1
```

{% endcode %}


# DDL/DCL/TCL

## DDL – Data Definition Language <a href="#ddl-data-definition-language" id="ddl-data-definition-language"></a>

{% hint style="info" %}
**Data Definition Language (DDL)** – это группа операторов определения данных. Другими словами, с помощью операторов, входящих в эту группы, мы определяем структуру базы данных и работаем с объектами этой базы, т.е. создаем, изменяем и удаляем их.
{% endhint %}

### CREATE

```sql
// Создать базу данных database
CREATE DATABASE database

// Cоздать таблицу table
CREATE TABLE table (
    field INT,
    field2 VARCHAR(255),
    field3 INT
)

// Cоздать таблицу table c дополнительными параметрами
CREATE TABLE table (
    field INT PRIMARY KEY,
    field2 VARCHAR(255) NOT NULL,
    field3 INT NOT NULL DEFAULT 18
)    
```

### ALTER

```sql
// Добавить поле field в таблицу table
ALTER TABLE table
ADD field INT NOT NULL

// Переименовать поле field в таблице table
ALTER TABLE table
RENAME COLUMN field TO field_new

// Переименовать таблицу table
ALTER TABLE table
RENAME TO table_new 
```

### DROP

```sql
// Удалить базу данных database
DROP DATABASE database

// Удалить таблицу table
DROP TABLE table

// Удалить столбец field в таблице table
ALTER TABLE table
DROP COLUMN field
```

***

## DCL – Data Control Language <a href="#dcl-data-control-language" id="dcl-data-control-language"></a>

{% hint style="info" %}
**Data Control Language (DCL)** – группа операторов определения доступа к данным. Иными словами, это операторы для управления разрешениями, с помощью них мы можем разрешать или запрещать выполнение определенных операций над объектами базы данных.
{% endhint %}

### GRANT

```sql
// Предоставить пользователю user права на чтение в таблице table
GRANT SELECT ON table TO user

// Предоставить пользователю user права на запись в таблицу table
GRANT INSERT ON table TO user
```

### REVOKE

```sql
// Отозвать у пользователя user права на чтение в таблице table
REVOKE SELECT ON table TO user

// Отозвать у пользователя user права на запись в таблицу table
REVOKE INSERT ON table TO user
```

### DENY

```sql
// DENY > REVOKE
//Запретить пользователю user разрешение на чтение таблицы table 
//независимо от того, какие разрешения этот пользователь мог унаследовать от роли
DENY SELECT ON table TO user
```

***

## TCL – Transaction Control Language <a href="#tcl-transaction-control-language" id="tcl-transaction-control-language"></a>

{% hint style="info" %}
**Transaction Control Language (TCL)** – группа операторов для управления транзакциями. Транзакция – это команда или блок команд (инструкций), которые успешно завершаются как единое целое, при этом в базе данных все внесенные изменения фиксируются на постоянной основе или отменяются, т.е. все изменения, внесенные любой командой, входящей в транзакцию, будут отменены.
{% endhint %}

**Транзакция** — это набор SQL-запросов, выполняемых над данными, которые объединены в атомарную секцию. Это значит, что промежуточные результаты операции не видны для других конкурирующих транзакций — и вся секция будет либо выполнена, либо полностью отменена в случае ошибки.

### BEGIN/COMMIT

```sql
// Выполнение кода текущей транзакции. Например INSERT в таблицу table
BEGIN TRANSACTION
INSERT INTO table (field1, field2)
VALUES ('value_field1', 'value_field2')
COMMIT
```

### BEGIN/ROLLBACK

```sql
// Откатывает текущую транзакцию и отменяет все обновления, сделанные транзакцией
BEGIN TRANSACTION
INSERT INTO table (field1, field2)
VALUES ('value_field1', 'value_field2')
ROLLBACK
```

Источник:

* <https://info-comp.ru/what-is-ddl-dml-dcl-tcl>
* <https://sky.pro/media/gruppy-operatorov-sql/>


# Представления VIEW

* <https://sql-academy.org/ru/guide/view>


# Констрейты

NOT NULL, UNIQUE, CHECK, DEFAULT, PRIMARY KEY,  FOREIGN KEY

{% hint style="info" %}
**Ограничения (constraints) в SQL** — это инструменты, которые позволяют ограничить или задать правила для данных, хранящихся в таблицах баз данных. Эти ограничения могут быть применены к одному или нескольким столбцам в таблице и обеспечивают целостность данных и защиту от ошибок ввода.
{% endhint %}

## NOT NULL

Ограничение NOT NULL в SQL определяет, что значение в столбце не может быть NULL. Если попытаться вставить NULL значение в столбец с ограничением NOT NULL, то будет выдана ошибка.

<details>

<summary>Пример SQL</summary>

```sql
//Создание таблицы
CREATE TABLE users
(
id int PRIMARY KEY,
name varchar(50) NOT NULL,
email varchar(50) NOT NULL 
);

//Изменение таблицы
ALTER TABLE users ALTER COLUMN name SET NOT NULL;
```

</details>

## UNIQUE <a href="#unique" id="unique"></a>

Ограничение уникальности **(UNIQUE)**  в SQL определяет, что значения в столбце должны быть уникальными. Значения в столбце могут быть NULL, но не более одного NULL значения разрешено.

<details>

<summary>Пример SQL</summary>

```sql
//Создание таблицы
CREATE TABLE users 
( 
id int PRIMARY KEY,
name varchar(50),
email varchar(50) UNIQUE 
);

//Изменение таблицы
ALTER TABLE users ADD CONSTRAINT email_unique_constraint UNIQUE (email);
```

</details>

## CHECK

Ограничение CHECK в SQL определяет условие, которое должно быть выполнено для всех значений в столбце. Если значение не соответствует условию, то будет выдана ошибка.

<details>

<summary>Пример SQL</summary>

```sql
//Создание таблицы
CREATE TABLE employees
( 
id int PRIMARY KEY,
name varchar(50),
salary decimal(10, 2) CHECK (salary > 0) 
);

//Изменение таблицы
ALTER TABLE employees ADD CONSTRAINT salary_constraint CHECK (salary > 0);
```

</details>

## DEFAULT <a href="#default" id="default"></a>

Ограничение DEFAULT в SQL позволяет установить значение по умолчанию для столбца в таблице базы данных. Если при вставке новой строки в таблицу не указано значение для столбца, то будет использоваться значение по умолчанию.

<details>

<summary>Пример SQL</summary>

```sql
//Создание таблицы
CREATE TABLE employees
(
id int PRIMARY KEY,
name varchar(50),
salary decimal(10, 2) DEFAULT 5000.00
);

//Изменение таблицы
ALTER TABLE employees ALTER COLUMN salary SET DEFAULT 5000.00;
```

</details>

## PRIMARY KEY <a href="#primary-key" id="primary-key"></a>

Ограничение первичного ключа **(PRIMARY KEY)** в SQL определяет уникальный идентификатор для каждой строки в таблице. Значения в столбце PRIMARY KEY должны быть уникальными и не могут быть NULL.

<details>

<summary>Пример SQL</summary>

```sql
//Создание таблицы
CREATE TABLE users 
( 
id int PRIMARY KEY,
name varchar(50),
email varchar(50)
);

//Изменение таблицы
ALTER TABLE users ADD PRIMARY KEY (id);
```

</details>

## FOREIGN KEY <a href="#foreign-key" id="foreign-key"></a>

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

<details>

<summary>Пример SQL</summary>

```sql
//Создание таблицы
CREATE TABLE users 
( 
id int PRIMARY KEY,
name varchar(50),
address_id int,
FOREIGN KEY (address_id) REFERENCES addresses(id)
); 

CREATE TABLE addresses 
( 
id int PRIMARY KEY,
street varchar(50),
city varchar(50),
state varchar(50) 
);

//Изменение таблицы
ALTER TABLE users ADD CONSTRAINT address_id_foreign_key_constraint FOREIGN KEY (address_id) REFERENCES addresses(id);
```

</details>

Источники:

* <https://itonboard.ru/analysis/data_analysis/370-ogranicheniia_v_sql/>


# Типы данных

## Целые числа

Хранят только целые числа, без дробной части. Делятся на signed (со знаком) и unsigned (без знака).&#x20;

* Типы singed позволяют хранить как положительные, так и отрицательные значения.
* Типы unsigned хранят только положительные числа, но зато диапазон значений больше. Это может быть полезно в случаях, когда хранимые значения заведомо не могут быть отрицательным. Например, количество товара или идентификатор записи в таблице.

Примеры: TINYINT, SMALLINT, MEDIUMINT, **INT**, BIGINT

## Числа с плавающей точкой

Хранят приблизительные значения. Не резервируют определенное количество бит для целочисленной или дробной частей. Поэтому у всех значений в таблице количество до и после запятой будет разным.

Примеры: **FLOAT, DOUBLE**

## Числа с фиксированной точкой

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

Примеры: **DECIMAL(M,D), NUMERIC(M,D)**

## Символьные (строковые) <a href="#symbolic" id="symbolic"></a>

* **CHAR** хранит строку фиксированной длины до 255 символов. Если длина вставляемой записи меньше, то MySQL автоматически дополняет значение пробелами.&#x20;
* **VARCHAR** хранит строки переменной длины до 65 535 символов. Причем в памяти хранится именно та длина, которая была указана при создании. VARCHAR занимает меньше места, чем CHAR, но подвержен фрагментации и из-за этого может проигрывать в скорости обработки данных.

## Текстовые и бинарные <a href="#text-and-binary" id="text-and-binary"></a>

Текстовые (TEXT) и бинарные (BLOB) типы данных используются для хранения больших объемов текста или двоичных данных. Эти типы похожи, но отличаются по способу хранения и обработки внутри MySQL.

* **BLOB** обрабатывается как двоичные данные. В нем не хранится набор символов, а операции сортировки и сравнения основаны на числовых значениях байтов.&#x20;
* **TEXT** обрабатывается как символьные строки. В нем хранится именно набор символов, а значения сортируются и сравниваются на основе сопоставления набора символов..

Текстовые типы отлично подходят для хранения больших текстов: статей, докладов и так далее. А бинарные типы могут хранить любые файлы или мультимедиа-контент.

## Дата/время <a href="#date" id="date"></a>

Примеры: **DATE, DATETIME, TIMESTAMP, TIME**

Источник: <https://selectel.ru/blog/tutorials/data-types-in-mysql/>


# Middle+


# Особенности работы с конкертными реляционными БД


# Нереляционные

{% hint style="info" %}
**Нереляционная база данных** — это база данных, в которой в отличие от большинства традиционных систем баз данных не используется табличная схема строк и столбцов. В этих базах данных применяется модель хранения, оптимизированная под конкретные требования типа хранимых данных. Например, данные могут храниться как простые пары "ключ — значение", документы JSON или граф, состоящий из ребер и вершин.
{% endhint %}

## Особенности NoSQL <a href="#osobennosti-nosql" id="osobennosti-nosql"></a>

Термин объединяет множество СУБД, имеющих различную архитектуру и характеристики. Однако, можно выделить несколько присущих им всем особенностей:

* **Неструктурированность.** В NoSQL-базах структура данных не регламентирована вообще или лишь в малой степени. Если нужно внести изменения в поля отдельного документа, для этого не потребуется декларативно менять всю структуру таблицы. При необходимости поменять модель данных потребуется просто указать изменения в коде приложения.
* **Использование альтернатив SQL.** В нереляционных базах данных не применяется классический SQL, а используются различные SQL-диалекты.
* **Агрегация данных.** В то время как реляционные БД сохраняют данные в виде таблиц, в нереляционных они представляют собой целостные объекты.&#x20;
* **Распределенность.** В нереляционных базах данных реализована горизонтальная масштабируемость. Она достигается за счет соединения быстрым подключением нескольких независимых друг от друга серверов, каждый из которых обрабатывает только часть данных, а не весь массив. Соответственно, нет необходимости наращивать мощность каждого сервера (тем более что есть физический предел) — достаточно просто добавить в систему новый.

## Виды NoSQL-баз данных <a href="#vidy-nosqlbaz-dannykh" id="vidy-nosqlbaz-dannykh"></a>

* **Ключ-значение.** В таких БД для доступа к значению используется ключ. Они применяются в качестве хранилищ изображений, специализированных файловых систем, кэшей, информационных платформ для онлайн-игр и т.д. — везде, где главными требованиями являются высокая масштабируемость и минимальная задержка обработки запроса.
* **Матричные.** В таких БД данные хранятся в виде разреженных матриц, где строки и столбцы используются как ключи доступа к значению. Чаще всего такие СУБД применяют в индексировании веб-страниц и других задачах, связанных с обработкой больших данных.
* **Документо-ориентированные.** В базах данных этого типа данные записываются в специальный документ в формате JSON или близком к нему. Таким БД свойственны одновременно иерархичность и гибкость. Чаще всего они применяются в системах управления контентом, каталогах, специализированных поисковых системах (например, в электронных архивах).
* **Графовые.** Такие БД сохраняют информацию в виде сложно связанных друг с другом графов. Связанность данных упрощает их хранение, навигацию и поиск. Типичными примерами использования графовых БД являются социальные сети, системы выявления мошенничества.

## Преимущества NoSQL <a href="#preimushestva-nosql" id="preimushestva-nosql"></a>

* **Горизонтальная масштабируемость —** для увеличения производительности достаточно добавить новый сервер в систему, а не наращивать мощности уже имеющихся.
* **Высокая устойчивость —** так как NoSQL-БД размещаются на независимых серверах, выход одного из них из строя не обрушит всю базу данных и, следовательно, не приведет к полному отказу приложения.
* **Производительность —** с одной стороны, каждый сервер обрабатывает только свои запросы, не растрачивая свои мощности на все; с другой — информационные модели таких СУБД адаптируются под специфику каждого приложения.
* **Гибкость —** нереляционные БД могут работать с неструктурированными данными и различными моделями представления информации.

## Недостатки NoSQL <a href="#nedostatki-nosql" id="nedostatki-nosql"></a>

* **Ограниченность языка —** встроенные языковые возможности нереляционных баз данных, из-за чего в работе с ними часто приходится использовать сторонние инструменты для трансляции стандартных SQL-команд.
* **Недостаточная надежность транзакций —** из-за того, что NoSQL-БД заточены под высокую производительность и масштабируемость, в них страдает согласованность данных (ACID), критически важная для таких сфер, как денежные переводы.

## Примеры нереляционных СУБД

1. **MongoDB**. Данная система хранения информации основана на *формате документа*. Она применяет документ вида JSON для того, чтобы сохранять информацию. С ее помощью можно легко и быстро масштабировать информацию и поддержать гибкую модель информации.&#x20;
2. **Cassandra**. Данная система хранения информации основана на *колонках*. Ее используют для обработки огромного количества информации. С ее помощью можно получить высокую доступность, она отлично масштабируется, к тому же поддерживает гибкую модель информации.&#x20;
3. **Redis**. Данная система хранения информации основана на *ключ-значениях*. Ее используют для кэша информации и убыстрения получения доступа к ним. Ее применяют и для хранения данных иного типа вроде наборов и списков. &#x20;
4. **Neo4j**. Данная система хранения информации основана на *графах*. Ее используют для оценки связей между информацией. С ее помощью можно получить высокие показатели эффективности и создать гибкую модель информации, из-за чего она становится прекрасной для обработки данных, которые связаны между собой.&#x20;
5. **Amazon DynamoDB**. Фактически это услуга по регуляции баз данных от компании Amazon. Она применяет модель *ключ-значение* для того, чтобы хранить информацию. С ее помощью можно получить высокий уровень доступа и легко масштабировать данные, к тому же гарантируется низкая задержка в случае доступа к информации.&#x20;

Источники:&#x20;

* <https://blog.skillfactory.ru/glossary/nosql/>
* <https://wiki.fenix.help/informatika/nerelyacionnye-bazy-dannyh>

Подробнее:&#x20;

* <https://learn.microsoft.com/ru-ru/azure/architecture/data-guide/big-data/non-relational-data>


# Примеры использования

## Ключ-значение

В базах данных «ключ-значение» для хранения информации вы предоставляте ключ и объект данных, который нужно сохранить. Например, JSON-объект, изображение или текст. Чтобы запросить данные, отправляете ключ и получаете value. Данные в value хранятся строго в виде blob-объектов.

### Пример использования

1. Ключ — это название страны, а значение — список адресов магазинов в этой стране
2. Ключ — это идентификатор клиента, а значение — краткая информация о клиенте

### Примеры БД

* Redis
* Memcached
* DynamoDB
* Riak

## Документо-ориентированные

Документные базы данных (документоориентированные БД), совместно используют базовую семантику доступа и поиска хранилищ ключей и значений. Такие БД также используют ключ для уникальной идентификации данных. Разница между хранилищами «ключ-значение» и документными БД заключается в том, что вместо хранения blob-объектов, документоориентированные базы хранят данные в структурированных форматах – JSON, BSON (бинарный JSON) или XML.

### Пример использования

Document-oriented-модель хороша в проектах, где нужно обрабатывать большой объём данных без четкой структуры, а также для работы со множеством уникальных документов, которые со временем требуют изменений. Например, для каталогов товаров, соцсетей, платформ с блогами и видео, геоаналитики и в других сферах.

### Примеры БД

* [MongoDB ](#user-content-fn-1)[^1]
* CouchDB

## Графовые

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

### Пример использования

1. Любой рейтинг «Рекомендовано вам», который можно увидеть на разных сайтах, зачастую составляется исходя из того, как другие пользователи оценили продукт. Графовые базы данных отлично подходят для такого случая.
2. Используются для выполнения задач, ориентированных на связи: для алгоритмов рекомендаций контента, социальных сетей, обнаружения случаев сетевого мошенничества.

### Примеры БД

* Neo4j
* JanusGraph

## Колоночные

Модель колоночных баз данных основана на идее хранения данных в виде отдельных колонок, а не строк, как в традиционных реляционных базах данных. Это позволяет более эффективно хранить и обрабатывать данные, особенно в случаях, когда нужно работать с большими объемами информации.

### Пример использования

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

### Примеры БД

* ClickHouse
* Vertica
* Cassandra

Источники:&#x20;

* <https://tproger.ru/translations/types-of-nosql-db>
* <https://proglib.io/p/11-tipov-sovremennyh-baz-dannyh-kratkie-opisaniya-shemy-i-primery-bd-2020-01-07>
* <https://cloud.yandex.ru/ru/blog/posts/2022/10/nosql>
* <https://habr.com/ru/companies/otus/articles/760226/>

[^1]: песочница <https://mongoplayground.net/>


# Middle+


# Колоночные

{% hint style="info" %}
**Колоночные базы данных** (Columnar Databases) - это тип баз данных, где данные хранятся и организуются по колонкам, в отличие от традиционных реляционных баз данных, где данные хранятся по строкам. В колоночных базах данных каждая колонка содержит данные одного типа, и они компактно хранятся в сжатом формате.
{% endhint %}

## Преимущества

* быстрое выполнение запросов на чтение данных
* более эффективное использование памяти, чем в строчных бд
* лучшую сжимаемость данных, чем в строчных бд
* более простая масштабируемость БД
* низкие требования к консистентности данных
* распределенные вычисления и распараллеливание запросов (MPP)
* шардирование данных (хранение по частям на разных хостах)

## Примеры

Некоторые известные колоночные базы данных:&#x20;

* Сlickhouse
* Apache Cassandra
* Vertica

## Где применяются

Колоночные таблицы обычно хорошо подходят для аналитических и OLAP[^1] задач, где требуется обработка больших объемов данных.

{% content-ref url="/pages/cBpaN1FWvW8Ien6uNR6Q" %}
[OLAP](/hard-skills/bazy-dannykh/khranenie-i-analiz-dannykh/olap)
{% endcontent-ref %}

Источник: <https://backendinterview.ru/db/column/index.html>

[^1]: OLAP (OnLine Analytical Processing) — оперативная аналитическая обработка данных или анализ данных в реальном времени.


# Сlickhouse


# Ключ-значение


# Матричные


# Документо-ориентированные


# Графовые

Источники:&#x20;

* <https://wiki.merionet.ru/articles/chto-takoe-grafovaya-baza-dannyh/>


# JanusGraph | Neo4j etc


# Масштабирование БД

## Вертикальное масштабирование <a href="#rt-0" id="rt-0"></a>

Вертикальное масштабирование предполагает наращивание мощностей сервера. Основным преимуществом метода является его простота. Нет необходимости переписывать код при добавлении мощностей, а управлять одним крупным сервером намного проще, чем целой системой. Это же является и основным недостатком — масштабирование ресурсов одного сервера имеет вполне конкретные аппаратные ограничения. Также стоит учесть стоимость такого решения: сервер с кратным объёмом вычислительных ресурсов в большинстве случаев оказывается дороже, чем несколько менее мощных серверов, дающих в сумме такую производительность.

## Горизонтальное масштабирование <a href="#rt-1" id="rt-1"></a>

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

<table data-full-width="true"><thead><tr><th>Область сравнения</th><th>Репликация</th><th>Партицирование</th><th>Шардирование</th></tr></thead><tbody><tr><td>Основная функция</td><td>Повышение стабильности</td><td>Повышение управляемости</td><td>Ускорение обработки</td></tr><tr><td>Метод</td><td>Копирование между серверами</td><td>Разбиение по функциональности</td><td>Разбиение по объему</td></tr><tr><td>Распределение</td><td>По ведущим и ведомым серверам</td><td>Потоковое</td><td>Физическое</td></tr></tbody></table>

### Репликация <a href="#rt-2" id="rt-2"></a>

{% hint style="info" %}
**Репликация** — это синхронное или асинхронное копирование данных между несколькими серверами. Ведущие серверы часто называют мастерами (master), а ведомые серверы — слэйвами (slave).&#x20;
{% endhint %}

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

Главное преимущество репликации — большое количество копий данных. Так, если даже головной сервер выходит из строя, любой другой сможет его заменить. Однако как механизм масштабирования репликация не слишком удобна. Причина тому — рассинхронизация и задержки при передаче данных между серверами. Чаще всего репликация используется как средство для обеспечения отказоустойчивости вместе с другими методами масштабирования.

*Например, создание нескольких дополнительных slave‑серверов позволяет снять с основного сервера нагрузку и повысить общую производительность системы, а также можно организовать слэйвы под конкретные ресурсоёмкие задачи и таким образом, например, упростить составление серьёзных аналитических отчётов — используемый для этих целей slave может быть нагружен на 100%, но на работу других пользователей приложения это не повлияет.*

### Партицирование (секционирование) <a href="#rt-3" id="rt-3"></a>

{% hint style="info" %}
**Партиционирование** — это разбиение таблиц, содержащих большое количество записей, на логические части по неким выбранным администратором критериям.&#x20;
{% endhint %}

Партиционирование таблиц делит весь объем операций по обработке данных на несколько независимых и параллельно выполняющихся потоков, что существенно ускоряет работу СУБД. Для правильного конфигурирования параметров партиционирования необходимо, чтобы в каждом потоке было примерно одинаковое количество записей.

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

### Шардирование (шардинг/сегментирование) <a href="#rt-4" id="rt-4"></a>

{% hint style="info" %}
**Шардинг** — это прием, который позволяет распределять данные между разными физическими серверами.&#x20;
{% endhint %}

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

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

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

Источники:&#x20;

* <https://simpleone.ru/blog/masshtabirovanie-baz-dannyh/>
* <https://web-creator.ru/articles/partitioning_replication_sharding>
* <https://cloud.yandex.ru/ru/docs/glossary/sharding>


# Оптимизация БД

Добавь базе скорость

## Индексы в таблицах

{% hint style="info" %}
**Индексирование баз данных** — это техника, повышающая скорость и эффективность запросов к базе данных. Она создаёт отдельную структуру данных, сопоставляющую значения в одном или нескольких столбцах таблицы с соответствующими местоположениями на физическом накопителе, что позволяет базе данных быстро находить строки по конкретному запросу без необходимости сканирования всей таблицы.&#x20;
{% endhint %}

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

### Алгоритмы индексирования

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

* B-дерево
* Bitmap-индекс
* Хэш-индекс
* GiST (Generalized Search Tree, обобщённое поисковое дерево)
* Полнотекстовый индекс

Рассмотрим самый простой и распростаненный способ индексирования - В-дерево.

## B-дерево

Перед нами B-дерево индекса, присвоенного полю в таблице (которое чаще всего используется при выборках). В каждом узле хранятся элементы со значениями.Также элементы хранят ссылку на строку в таблице.

<figure><img src="/files/DNmBCo8tWPi5sNVe26J5" alt=""><figcaption><p>Поиск значения 2001</p></figcaption></figure>

Поиск начинается с корневого узла. Наша задача — пройти по каждому элементу в узле и сравнить его значение с искомым:

* Если значение совпало — берём ссылку на данные и читаем их из таблицы.
* Если наше значение больше, чем значение в элементе, — идём дальше.
* Если искомое значение меньше, чем в элементе, — нам нужно перейти в поддерево, которое хранится левее от ячейки. Далее мы попадаем на следующий уровень и итерация повторяется.

Рассмотрим алгоритм на примере поиска значения 2001.

* Как и говорилось ранее, мы начинаем с корневого узла — первой ячейки со значением 1000.
* Так как 2001 больше 1000, то мы идём дальше.
* Доходим до ячейки 3000. Но 2001 меньше, чем 3000, поэтому переходим на поддерево.
* Первая ячейка идёт со значением 2200, наше значение меньше, значит снова переходим на левое поддерево.
* И сразу же находим ячейку со значением 2001.

То, что мы и искали. А так как искомая ячейка содержит ссылку на место, где лежат наши данные, то мы можем легко и быстро прочитать их.

Источники:

* <https://habr.com/ru/companies/ruvds/articles/724066/>
* <https://skillbox.ru/media/code/kak_uskorit_bazu_dannykh_s_pomoshchyu_indeksov/>
* <https://otus.ru/journal/vse-chto-neobhodimo-znat-pro-indeksy-ms-sql/> (почитать!)


# Типы индексов

## Кластеризованный индекс

* Только по одному на таблицу
* Быстрее читается, чем некластеризованный, поскольку данные физически хранятся в порядке индексации

## Некластеризованный индекс

* Может использоваться много раз для каждой таблицы
* Операции вставки и обновления выполняются быстрее, чем с кластеризованным индексом

Оба типа индекса повышают производительность при выборе данных с полями, использующими индекс, но замедляют операции обновления и вставки.

Из-за более медленной вставки и обновления кластеризованные индексы следует устанавливать в поле, которое обычно является инкрементным, т.е. идентификатором или меткой времени.

Источники:&#x20;

* <https://stackoverflow.com/questions/91688/what-are-the-differences-between-a-clustered-and-a-non-clustered-index>


# Уникальные индексы

{% hint style="info" %}
**Уникальным (Unique)** называют индекс, обеспечивающий уникальное значение всех строк по определенному ключу и гарантирующий, что в ключе индекса не будет значений одинаковых, повторяющихся. Для составного ключа понятие уникальности касается всех index columns, но не распространяется на каждый столбец в отдельности.
{% endhint %}

Если в таблице формируется Unique index одновременно по ряду столбцов, это означает, что абсолютно каждая вариация значений в ключе будет уникальной.

SQL сервером создается автоматически Unique index для ключевых столбцов при формировании ограничений UNIQUE либо PRIMARY KEY. Но он формируется лишь при выполнении условия отсутствия дублей в ключевых столбцах таблицы.

Уникальный индекс создается автоматом при определении ограничений столбца:

* первичным ключом (на один столбец либо сразу на несколько), при условии, что кластерный индекс ранее не создавался. В том случае, когда он все-таки уже создан, сервер создаст уникальный некластерный индекс по первичному ключу;
* ограничением на уникальность значений – сервером создается Unique Nonclustered index. Когда кластерный индекс не был сформирован заранее, есть возможность создания именно Unique Clustered index.

Источники:

* <https://postgrespro.ru/docs/postgresql/13/indexes-unique>
* <https://otus.ru/journal/vse-chto-neobhodimo-znat-pro-indeksy-ms-sql/#%D0%A3%D0%BD%D0%B8%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9>


# Анатомия плана запроса

Анатомия плана запроса в PostgreSQL: <https://sql-ex.ru/blogs/?/AnatomiJa\\_plana\\_zaprosa\\_v\\_PostgreSQL.html>

* EXPLAIN: <https://postgrespro.ru/docs/postgresql/14/sql-explain>
* ANALYZE: <https://postgrespro.ru/docs/postgresql/14/sql-analyze>


# Какую СУБД выбрать

| Тип СУБД      | Когда выбирать                                                                                                          | Примеры популярных СУБД                                                      |
| ------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| Реляционные   | Нужна транзакционность; высокая нормализация; большая доля операций на вставку                                          | Oracle, MySQL, Microsoft SQL Server, PostgreSQL                              |
| Ключ-значение | Задачи кэширования и брокеры сообщений                                                                                  | Redis, Memcached                                                             |
| Документные   | Для хранения объектов в одной сущности, но с разной структурой; хранение структур на основе JSON                        | CouchDB, MongoDB, Amazon DocumentDB                                          |
| Графовые      | Задачи подобные социальным сетям; системы оценок и рекомендаций                                                         | Neo4j, Amazon Neptune, InfiniteGraph, InfoGrid                               |
| Колоночные    | Хранилища данных; выборки со сложными аналитическими вычислениями; количество строк в таблице превышает сотни миллионов | Vertica, ClickHouse, Google BigTable, Sybase \ SAP IQ, InfoBright, Cassandra |

Источник:

* <https://habr.com/ru/articles/579248/>


# Хранение и анализ данных

<figure><img src="/files/R4DJnsHBPV28XO6CDsWR" alt=""><figcaption><p>Храненение и анализ данных</p></figcaption></figure>

## Архитектура хранилища данных

Довольно часто традиционная архитектура хранилища данных имеет трехуровневую структуру, состоящую из следующих ступеней:

### **Нижний уровень (Bottom Tier)**

Этот уровень содержит сервер базы данных, используемый для извлечения данных из множества различных источников, например, из транзакционных баз данных, используемых для интерфейсных приложений.

Основные компоненты этого уровня:

* **Источники данных**

Источниками данных могут являться например: реляционные базы данных, сведения с веб-сайта, из биллинговой системы, CRM- и ERP-систем и других баз данных.

* **ETL обработка**

ETL (Extract, Transform, Load) — извлечение, преобразование и загрузка. То есть процесс, с помощью которого данные из нескольких систем объединяют в единое хранилище данных (DWH).

* **DWH**

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

### **Средний уровень (Middle Tier)**

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

### **Верхний уровень (Top Tier)**&#x20;

Верхний уровень — это уровень клиента. Этот уровень содержит BI-инструменты, используемые для высокоуровневого анализа данных, создания отчетов и анализа данных.

Актуальные инструменты бизнес-аналитики (BI) вкупе с возможностями DWH позволяют принимать управленческие решения с гарантированным результатом. Благодаря эффективному анализу больших массивов данных менеджмент компании также может выдвигать гипотезы, построенные на реальных бизнес-показателях, и тестировать их.

Источники:

* <https://habr.com/ru/articles/441538/>
* <https://selectel.ru/blog/data-warehouse/>
* <https://cloud.mts.ru/cloud-thinking/blog/data-warehouse/>


# ETL

{% hint style="info" %}
**ETL** (Extract, Transform, Load) — это процесс извлечения данных из источников, их трансформации и загрузки в целевую систему или хранилище данных. ETL является ключевым компонентом при построении и обновлении хранилищ данных или аналитических систем.
{% endhint %}

Вот более подробное описание каждого шага в процессе ETL:

1. **Извлечение (Extract):** Этот шаг включает получение данных из различных источников, таких как базы данных, текстовые файлы, веб-сервисы и другие. Извлечение может быть выполнено с использованием различных методов, включая SQL-запросы, API-вызовы или прямое чтение файлов.
2. **Трансформация (Transform):** В этом шаге данные подвергаются различным преобразованиям и очистке для подготовки их к загрузке. В процессе трансформации могут выполняться операции, такие как фильтрация, агрегация, преобразование формата данных, устранение дубликатов и обогащение данных.
3. **Загрузка (Load):** После завершения трансформации данные загружаются в целевую систему или хранилище данных. Загрузка может быть выполнена в различные типы систем, такие как реляционные базы данных, хранилища данных, дата-озера или облачные хранилища.

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

Источник: <https://testengineer.ru/etl/>

Почитать:&#x20;

* <https://habr.com/ru/articles/248231/>
* <https://practicum.yandex.ru/blog/chto-takoe-etl/>


# DWH

{% hint style="info" %}
**Data Warehouse (DWH)** — это единое корпоративное хранилище архивных данных из разных источников. Цель Data Warehouse — обеспечить компанию возможностью принимать верные решения в ключе управления бизнесом на основе целостной информационной картины.
{% endhint %}

В DWH данные из всех СУБД предприятия аккумулируют и очищают, формируя их единый источник. Благодаря этому Data Warehouse содержит самую точную информацию обо всех аспектах деятельности предприятия за годы работы.

Данные из хранилища затем можно визуализировать и проанализировать с помощью систем бизнес-аналитики (BI). Расширенные функции BI — это поиск закономерностей и взаимосвязей в данных (Data Mining), искусственный интеллект, машинное обучение и средства визуализации результатов. Перечисленные инструменты помогают бизнесу находить новые возможности на рынке и быстро их реализовывать, отталкиваясь от данных и прогнозных моделей.

Однако возникает вопрос: зачем использовать для аналитики отдельное хранилище, а не анализировать данные в каждой СУБД по отдельности, ведь DWH — это тоже база данных?

## Отличия DWH от транзакционной БД <a href="#otlichiya-dwh-ot-tranzakcionnoj-bd" id="otlichiya-dwh-ot-tranzakcionnoj-bd"></a>

Дело в том, что Data Warehouse и транзакционные БД — это разные типы баз данных. Хранилище предназначено для анализа данных, которые поступают в него с определённой периодичностью — например, ежечасно или ежедневно. Оно разворачивается поверх СУБД и способно быстро обрабатывать большие массивы данных, собранные за несколько лет. DWH фактически — инструмент для комплексного анализа данных из множества источников: по товарам, сделкам, персоналу, логистике и т. д.

СУБД в основном предназначены не для аналитики, а для повседневной работы. Информация в них обновляется в реальном времени. В основе CRM, ERP, 1C и многих других систем и программ лежит именно функциональность БД. Актуальные сведения поступают сначала в основные БД, а уже оттуда значимые данные пересылаются в DWH. Таким образом удаётся получить целостную информационную картину.

## Архитектура Data Warehouse

<figure><img src="/files/A97wNmjFH9KRVXigsXQz" alt=""><figcaption><p>Архитектура DWH</p></figcaption></figure>

Одна из моделей проектирования Data Warehouse — «слоеный пирог», построенный по архитектуре LSA, Layered Scalable Architecture.&#x20;

Она реализует логическое деление структур с данными на несколько функциональных уровней:&#x20;

1. **Стейджинг (Primary Data Layer)** — уровень, на котором подгружаются данные из внешних источников. Например, из таблиц, ERP-системы или биллинговой системы.
2. **Ядро хранилища (Core Data Layer)** — центральный уровень, который подгоняет данные к единым структурам и ключам. На этом слое обеспечивается целостность и качество данных.&#x20;
3. **Аналитические витрины (Data Mart Layer)** — слой, который преобразует данные к структурам, удобным для анализа и использования в BI-дашбордах и других аналитических системах.&#x20;
4. **Сервисный слой (Service Layer)** — уровень, на котором обеспечивается управление предыдущими слоями, мониторинг и диагностика ошибок. &#x20;

### Модели

Существует две модели, описывающие то, как должны быть устроены хранилища данных. Их идейные вдохновители — Билл Инмон, «отец хранилищ данных», и Ральф Кимбалл, идейный лидер в области хранилищ многомерных данных.

* По **модели** **Инмона** **(Inmon)** данные из источников должны поступать в хранилище сразу после процесса ETL. &#x20;

<details>

<summary><strong>Преимущества/недостатки  подхода Инмона</strong> </summary>

**Преимущества подхода Инмона**

* Хранилище данных действует как единый источник истины для всего бизнеса, где все данные интегрированы.
* Этот подход имеет очень низкую избыточность данных. Таким образом, уменьшается вероятность сбоев в обновлении данных, что делает процесс хранилища данных ETL более простым и менее подверженным сбоям.
* Это упрощает бизнес-процессы, поскольку логическая модель представляет подробные бизнес-объекты.
* Этот подход обеспечивает большую гибкость, поскольку проще обновлять хранилище данных в случае каких-либо изменений в бизнес-требованиях или исходных данных.
* Он может обрабатывать разнообразные требования к отчетности в масштабе всего предприятия.

**Недостатки подхода Инмона**

* Сложность увеличивается со временем по мере добавления нескольких таблиц в модель данных.
* Требуются разработчики, обладающие навыками моделирования и проектирования хранилищ данных, которые могут быть дорогими и недоступными на рынке труда.
* Первичная разработка и ввод в эксплуатацию занимают много времени.
* Требуется дополнительная операция ETL, поскольку витрины данных создаются после создания хранилища данных.
* Этот подход требует от экспертов эффективного управления хранилищем данных.

</details>

* По **модели Кимбалла (Kimball)** после процесса ETL данные загружаются в витрины данных, а объединение витрин создает концептуальное (а не фактическое) хранилище данных.

<details>

<summary><strong>Преимущества/недостатки  подхода Кимбалла</strong></summary>

**Преимущества подхода Кимбалла**

* Kimball dimensional modeling позволяет быстро реализовывать хранилища данных поскольку не требуется нормализация данных, что позволяет быстро выполнять начальные фазы процесса проектирования хранилища данных.
* Преимущество звездообразной схемы состоит в том, что большинство операторов данных могут легко понять ее из-за ее денормализованной структуры, которая упрощает запросы и анализ.
* Площадь системы хранилища данных тривиальна, поскольку она ориентирована на отдельные области бизнеса и процессы, а не на все предприятие. Таким образом, хранилище занимает меньше места в базе данных, что упрощает управление системой.
* Это позволяет быстро извлекать данные из хранилища данных, поскольку данные разделяются на таблицы фактов и измерения. Например, таблица фактов и измерений для страховой отрасли будет включать транзакции по полисам и транзакции по претензиям.
* Для управления хранилищем данных достаточно небольшой группы проектировщиков и разработчиков, поскольку системы источников данных стабильны, а хранилище данных ориентировано на процессы. Кроме того, оптимизация запросов проста, предсказуема и управляема.
* Согласованная структура измерений для data quality framework. Подход Кимбалла также называют подходом к образу жизни, измеряющим бизнес, потому что он позволяет инструментам business intelligence глубже проникать в несколько звездообразных схем и дает надежную информацию.

**Недостатки подхода Кимбалла**

* Данные не полностью интегрированы до создания отчетности, идея «единого источника правды» потеряна.
* При обновлении данных в архитектуре Kimball DWH могут возникать не точные данные. Это связано с тем, что при использовании техник денормализации хранилища данных избыточные данные добавляются в таблицы базы данных.
* В архитектуре Kimball DWH проблемы с производительностью могут возникать из-за добавления столбцов в таблицу фактов, поскольку эти таблицы содержат довольно подробные сведения. Добавление новых столбцов может расширить размерность таблицы фактов, что повлияет на ее производительность (т.е. увеличится детализация хранилища данных). Кроме того, модель многомерного хранилища данных становится трудно изменить при любых изменениях потребностей бизнеса.
* Поскольку модель Кимбалла ориентирована на бизнес-процессы, вместо того, чтобы сосредоточиться на предприятии в целом, она не может удовлетворить все требования к отчетности бизнес-аналитики.
* Процесс включения больших объемов устаревших данных в хранилище данных сложен.

</details>

От выбора двух подходов будет зависеть исходный результат. Представим хранилище в виде картотеки — библиотечного шкафа с карточками, в котором хранятся данные.

* **По Инмону мы сначала берем 10 карточек, выписываем из них самое важное на листочек и кладем в шкаф.** Подобный подход используют в страховании. Сначала формируют общую картинку о всех застрахованных, собирают данные о доходе, возрасте, хронических болезнях, распространении определенных болезней в регионе, демографии, авариях на дорогах и пр. Все аспекты взаимосвязаны, поэтому сначала собираются все возможные данные, а после фильтруются и ложатся в основу модели.
* **По Кимбаллу мы начинаем с нескольких ящиков (витрин данных), а потом решаем, что сложить в общий шкаф.** Такой подход используют, например, в маркетинге: чтобы анализировать рекламные кампании не нужно знать абсолютно все, к метрикам нужно подходить выборочно.

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

Источник:

* <https://cloud.yandex.ru/blog/posts/2022/06/data-warehouse>
* <https://selectel.ru/blog/data-warehouse/>
* <https://ivan-shamaev.ru/data-engineering-etl-pipeline-data-warehouse-datalake/#i-3>


# DWH vs Data Lake vs Data Mart

## Решения для хранения данных, отличные от Data Warehouse <a href="#warehouse" id="warehouse"></a>

Хранилище содержит уже преобразованные, структурированные данные, готовые к последующей обработке и анализу. Это делает Data Warehouse удобным инструментом для решения бизнес-задач. Но DWH — не единственный способ хранения и аналитической обработки данных. Например, можно вспомнить Data Lake (озёра данных) и Data Mart (витрины данных). Эти подходы к работе с большими данными тоже активно используются компаниями. Попробуем сравнить их с Data Warehouse.

### Data Lake <a href="#data-lake" id="data-lake"></a>

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

### Data Mart <a href="#data-mart" id="data-mart"></a>

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

Источники:

* <https://cloud.yandex.ru/blog/posts/2022/06/data-warehouse>
* <https://selectel.ru/blog/data-warehouse/>


# OLAP

{% hint style="info" %}
OLAP (OnLine Analytical Processing) — оперативная аналитическая обработка данных или анализ данных в реальном времени.
{% endhint %}

## Хранение данных в OLAP системах <a href="#data-store" id="data-store"></a>

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

### **Многомерные хранилища (MOLAP)**

Такая система называется **MOLAP**.\
Для хранения строится OLAP-куб — многомерный массив данных, упорядоченный по измерениям или категориям.\
С помощью последних создаются информативные сводные таблицы. В центре куба расположена двумерная таблица фактов, которые характеризуют взаимодействие элементов из разных измерений.\
MOLAP — cамый быстрый вид аналитических систем: сервер напрямую извлекает из куба меры, которые соответствуют поступающим запросам.

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

### **Реляционные хранилища (ROLAP)**

Такая система называется **ROLAP**.\
Простое хранилище: данные нормализованы по множеству взаимосвязанных таблиц. Технология позволяет интегрировать систему OLAP с уже используемой, например, учетной системой.\
Недостаток системы ROLAP заключается в ее медлительности — ведь структура данных в хранилище не оптимизирована для OLAP. Система \**ROLAP* гораздо лучше масштабируется и способна анализировать обширные и подробные данные.

### **Гибридные решения**

Самая распространенная система OLAP — **HOLAP**.\
Объединяет возможности MOLAP и ROLAP: основные подробные данные находятся в реляционной базе данных, а множество предварительно рассчитанных мер — в кубе. Система обеспечивает самые оптимальные и эффективные решения.

## Требования к OLAP-системам <a href="#requirements" id="requirements"></a>

Вместе с понятием аналитической системы OLAP Эдгар Кодд предложил 12 критериев, по которым система признается таковой. Однако, по мнению некоторых специалистов, его подход оказался недостаточно конкретизированным, поэтому через некоторое время были предложены новые критерии, суть которых раскрывает аббревиатура FASMI — Fast Analysis of Shared Multidimensional Information, то есть быстрый анализ доступной многомерной информации. К аналитическим системам OLAP выдвигается пять основных требований:

1. **Скорость реакции (Fast)** — реакция системы должна быть быстрой: время между запросом и откликом не должно превышать пяти секунд. Это важно для оперативного представления информации в системах поддержки принятия решений, чтобы полученный результат строго соответствовал текущей ситуации.
2. **Аналитические возможности (Analysis)** — система должна выполнять любой логический, численный или статистический анализ, требуемый в рамках выполняемых задач, а также представлять и сохранять его результаты в доступном и наглядном виде.
3. **Доступность данных (Shared)** — данные в системе должны быть доступны множеству пользователей, но только в необходимом им объеме, который определяется механизмами разграничения прав или ролей.
4. **Многомерность представления (Multidimensional)** — данные должны быть представлены в многомерных иерархических структурах. Причем это должно отражаться не в физической структуре хранилища, а в логике пользовательских запросов. Это главное требование к системам OLAP.
5. **Релевантная информация (Information)** — система должна работать с нужными данными независимо от их расположения и объема. При этом наличие посторонних нерелевантных приложению данных может негативно сказаться на быстродействии и эффективности всей системы.

## Преимущества технологии OLAP <a href="#advantages" id="advantages"></a>

* **Прямой доступ к данным** — пользователь может извлечь и просмотреть любые существующие в базе данные без фильтрации и преобразования.
* **Все данные в одном месте** — OLAP позволяет реализовать общую платформу для поддержания всех аналитических процессов предприятия.
* **Неизменность данных** — огромные массивы данных в OLAP обработаны заранее и хранятся в неизменных специализированных архивах, что значительно ускоряет их комплексный анализ.
* **Универсальность** — OLAP-системы отличаются особой гибкостью: конечные пользователи могут извлекать произвольные данные, формировать любые отчеты и выполнять самые разные аналитические операции.
* **Быстрая детализация** итоговых данных — иерархическая многомерная структура хранения позволяет оперативно представлять результат анализа данных с нужной степенью детализации.
* **Высокая скорость формирования отчетов** — все данные рассчитаны заранее, поэтому при составлении отчета нужно дождаться только вывода результатов в заданном виде.
* **Возможность выявления скрытых зависимостей** — многомерность данных помогает обнаружить неочевидное влияние одних производственных процессов на другие.

Истчоник: <https://cloud.yandex.ru/docs/glossary/olap>

Почитать: <https://habr.com/ru/articles/126810/>\
Почитать на сайте нулевых: <http://www.olap.ru/basic/home.asp>


# OLAP vs OLTP

## Чем отличаются технологии OLAP и OLTP <a href="#differences" id="differences"></a>

| OLAP                                                                                                                                                                | OLTP                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| OLAP-системы хранят неизменные многомерные исторические данные и данные транзакций (зачастую собранные системами OLTP), позволяя получать по ним сложную аналитику. | OLTP — OnLine Transaction Processing — это технология обработки транзакций в реальном времени. Она обеспечивает непрерывное занесение данных в базу, их модификацию и извлечение. Данные размещаются в простых таблицах и, как следствие, занимают не так много места в хранилище. Но главное: OLTP-системы не предназначены для комплексного анализа данных, скорее, это инструмент их массового сбора и преобразования. |
| Назначение: Аналитики данных, которые собираются в приложениях                                                                                                      | Назначение: Пользователи приложений, где происходит обмен данными                                                                                                                                                                                                                                                                                                                                                         |

Источник: <https://cloud.yandex.ru/docs/glossary/olap>


# BI-аналитика

Понятное дело, что просто так тратить деньги и время на консервирование кучи разных записей, которые и так можно накопать в других базах данных, никто не станет. Ответ заключается в том, что DWH необходима для того, чтобы делать BI — business intelligence.

Что такое BI с DWH? BI-аналитика — это процесс анализа данных и получения информации, помогающей компаниям принимать решения.

{% hint style="info" %}
BI-аналитик — специалист, который анализирует данные в компании с помощью определенных инструментов и методики бизнес-интеллекта (BI — business intelligence). Он преобразовывает сырые сведения, собранные из разных источников, в ценную и удобную для восприятия информацию, которая поможет принять стратегические и тактические решения в организации.
{% endhint %}

## Чем занимается BI-аналитик

BI-аналитик решает много задач. Он собирает, анализирует и визуализирует данные, формирует отчеты и панели управления, взаимодействует с другими отделами. Остановимся подробнее на его обязанностях:&#x20;

* **Сбор данных из базы, систем управления бизнес-процессами CRM и планирования бизнеса ERP, веб-аналитики, медиа, соцсетей и других источников**. BI-аналитик определяет, что именно ему потребуются для анализа и разработки отчетов, работает над получением данных и интеграцией.
* **Очистка и структурирование данных.** Удаляет дубликаты, исправляет ошибки, заполняет пробелы и приводит данные в единый формат (Data Warehouse), чтобы обеспечить их целостность и однородность.
* **Анализ данных**. BI-аналитик применяет разные методы анализа: статистические модели, машинное обучение и другие методологии, чтобы выявить взаимосвязи и тренды. Анализ может включать определение ключевых метрик бизнеса, проведение сегментации (*ред.:* группировки по схожим признакам) аудитории, оценку эффективности маркетинговых кампаний и пр.
* **Визуализация данных в виде графиков, диаграмм, панелей управления и отчетов**. Аналитик использует специализированные инструменты BI. Например, Tableau, Power BI, QlikView, Excel и Powerpoint. Программы помогают визуализировать результаты анализа и облегчить их понимание для других сотрудников компании.
* **Создание отчетов и панелей управления, которые предоставляют структурированную информацию бизнесу.** Определяет ключевые показатели эффективности (KPI) и создает метрики измерения для отслеживания производительности компании и достижения поставленных целей.
* **Взаимодействие с другими отделами компании: маркетологами, финансистами и менеджерами по продажам.** BI-аналитику нужно понимать их потребности в аналитической информации. Он проводит совещания и консультации с коллегами, чтобы определить, какие аналитические решения и отчеты могли бы им помочь в работе.\
  BI-аналитик предоставляет сведения, которые понадобятся для принятия управленческих решений на всех уровнях компании. Он не только работает с данными, но и обеспечивает связь между различными отделами компании.
* **Мониторинг и оптимизация.** BI-аналитик отслеживает актуальность созданных отчетов и принятых решений, анализирует эффективность их использования в компании. Он находит потенциальные улучшения и оптимизации, чтобы обеспечить более точный и полезный анализ данных.

Источники:&#x20;

* <https://cloud.vk.com/blog/chto-takoe-dwh-i-pochemu-bez-nih-dannye-kompanii-bespolezny>
* <https://blog.skillbox.by/kod/kak-stat-bi-analitikom/>


# Интеграции

## Вопросы на которые ответим:

* Какие форматы данных используются для передачи данных?
  * Что такое JSON? Для чего используется?
  * Что такое XML и что в нем содержится?
  * Чем отличаются форматы XML и JSON?
  * (\*) Что такое XSD?
  * Что такое JSON схема и для чего она нужна?
* Какие виды и способы интеграций систем вы знаете?
* Что такое синхронные и асинхронные вызовы? Чем отличаются синхронное и асинхронное взаимодействия?
* Что такое HTTP?
  * Какие основные HTTP методы знаете?
  * Расскажите про HTTP сообщения. Какую структуру имеет запрос? Какую структуру имеет ответ? Какие коды состояния (status code) знаете и что они означают?
  * Что знаете про концепцию CRUD?
* Что такое API?
* Какие виды API бывают?
* Что такое REST API?
  * Проектировали ли вы API? Каким образом описывали спецификации?
  * Какие методы REST вы знаете?
  * Чем POST отличается от GET? Чем отличается POST от PUT?
  * (\*) Что такое идемпотентность?
  * (\*) Что содержит HEADER в ответе REST?
  * (\*) В каких местах (четырех) мы можем передать атрибуты в запросе? (Path, Body, Query, Header).
  * (\*) Чем отличается ошибка 200 от 201?
  * (\*\*) Напишите пример REST API для книжной библиотеки (напишите методы, эндпоинты и пример JSON)
  * Тестировали ли вы сами API? Какое ПО использовали?
* Чем REST отличается от SOAP?
* (\*) Что такое WSDL?
* Что такое асинхронное взаимодействие?
  * Что такое брокер сообщений?
  * Для чего нужны massages broker?
  * Что такое топик? Что такое партиция?
  * (\*) Что такое гарантированная доставка сообщений и какими механизмами ее можно обеспечить?
  * (\*) Отличия RabbitMQ и Kafka


# Форматы данных

Некоторые из популярных форматов данных включают:

1. **CSV (Comma-Separated Values):** CSV — это текстовый формат данных, в котором значения разделены запятыми. Он широко используется для обмена данных между различными приложениями и является одним из самых простых форматов для чтения и записи данных.
2. **JSON (JavaScript Object Notation):** JSON — это формат данных, основанный на синтаксисе JavaScript, и он используется для представления структурированных данных. JSON является популярным форматом для передачи данных между клиентом и сервером в веб-приложениях.
3. **XML (eXtensible Markup Language):** XML — это язык разметки, используемый для описания структуры данных. Он может быть использован для хранения и обмена сложных данных и широко применяется в веб-службах и других системах.
4. **YAML (YAML Ain’t Markup Language):** YAML является языком разметки, который обычно используется для конфигурационных файлов, передачи данных между программами и хранения простых структурированных данных.
5. **Excel:** Формат файла Excel (.xlsx) является популярным для хранения табличных данных. Он широко используется в бизнес-аналитике и финансовой отчетности, и обладает множеством функций для работы с данными, формулами и графиками.

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

Источник: <https://testengineer.ru/formaty-dannykh-data-formats/>


# JSON + JSON Schema

{% hint style="info" %}
JSON (JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript.
{% endhint %}

## Ограничения и синтаксис JSON

Допустимые форматы данных для пары "key":"value" в JSON указаны в карточках ниже:

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td><strong>Ключ "key"</strong></td><td>string</td><td></td></tr><tr><td><strong>Значение "value"</strong></td><td>string<br>number (integer)<br>object<br>array<br>boolean<br>null</td><td></td></tr></tbody></table>

Основные правила синтаксиса:

1. Данные записываются в виде пар {“ключ”: значение}.
2. Данные разделяются запятыми.
3. В фигурных скобках записываются объекты.
4. В квадратных скобках записываются массивы.
5. Наименования «ключей» регистрозависимы.

<details>

<summary>Пример JSON</summary>

```json
{
    "students": [
        {
            "id": 101,
            "name": "Max",
            "score": {
                "Math": 90,
                "Science": 80,
                "Compute": 70
            }
        },
        {
            "id": 102,
            "name": "Sam",
            "score": {
                "Math": 76,
                "Science": 80,
                "Compute": 66
            }
        }
        ],
    "name_school": "EKB Lyceum",
    "name_teacher": "TO"
}
```

</details>

## JSON Schema

{% hint style="info" %}
JSON Schema – это своеобразный язык описания структуры JSON-документации. Базируется на разных концепциях. Выступает в качестве самоописательного языка.
{% endhint %}

Схема создана для описания JSON-данных, но и сама она при этом является JSON-объектом. С помощью ключевых слов (keywords) в схеме создаются правила валидации структуры объекта и типов его полей.

<details>

<summary>Простой пример JSON</summary>

```json
{
  "id": 210700286,
  "first_name": "Lindsey",
  "last_name": "Stirling"
}
```

</details>

<details>

<summary>Пример простой JSON Schema</summary>

```json
{
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "description": "User ID"
        },
        "first_name": {
          "type": "string",
          "description": "User first name"
        },
        "last_name": {
          "type": "string",
          "description": "User last name"
        }
      },
      "required": [
        "id",
        "first_name",
        "last_name"
      ]
}
```

</details>

## "Keywords" для описания схемы

<table data-full-width="true"><thead><tr><th width="176">Keywords</th><th width="183">Описание</th><th>Пример</th></tr></thead><tbody><tr><td><code>"$schema"</code></td><td>Используется для задания версии драфта схемы</td><td><p></p><pre><code>"$schema": http://json-schema.org/draft-04/schema#
</code></pre></td></tr><tr><td><code>"$id"</code></td><td>Используется для указания уникального идентификатора документа или его подсхем.</td><td><p></p><pre><code>"$id": "http://archi-blair.com/schemas/RolesDictionaryDef.json#"
</code></pre></td></tr><tr><td><code>"title" "description" "examples" "comment"</code></td><td>Комментарии к JSON схеме</td><td></td></tr></tbody></table>

## "Keywords" зависимые от типа данных

### `Тип данных: "type": "string"`

<table data-full-width="true"><thead><tr><th width="136">Keywords</th><th width="240">Описание</th><th width="342">Пример JSON Shema</th><th>Примеры JSON сообщения</th></tr></thead><tbody><tr><td>minLength<br>maxLength</td><td>Длину строки string можно ограничить с помощью ключевых слов <strong>minLength</strong> и <strong>maxLength</strong>. Для обоих ключевых слов значение должно быть неотрицательным числом.</td><td><pre><code>{
  "type": "string",
  "minLength": 2,
  "maxLength": 3
}
</code></pre></td><td><pre><code>// Положительный кейс 
{ "АB" } или { "АBС" }

// Отрицательный кейс
{ "АBCD" } </code></pre></td></tr><tr><td>pattern</td><td>Формат строки string можно ограничивать с помощью ключевого слова pattern. Паттерн задается с помощью регулярного выражения RegEx</td><td><pre><code>{
"type": "string",
"pattern": "^(\\(\[0-9]{3}\\))?\[0-9]{3}-\[0-9]{4}$"
} </code></pre></td><td><pre><code>// Положительный кейс
{ "555-1212" }

// Отрицательный кейс
{ "(800)FLOWERS" } </code></pre></td></tr></tbody></table>

### `Тип данных: "type": "number"`

<table data-full-width="true"><thead><tr><th width="192">Keywords</th><th width="240">Описание</th><th>Пример JSON Shema</th><th>Примеры JSON сообщения</th></tr></thead><tbody><tr><td>minimum<br>maximum<br>exclusiveMinimum<br>exclusiveMaximum </td><td><p>Диапазон числа number можно ограничивать с помощью ключевых слов.</p><p>Если x - это проверяемое значение, то должно выполняться следующее:</p><ul><li>x ≥ minimum</li><li>x > exclusiveMinimum</li><li>x ≤ maximum</li><li>x &#x3C; exclusiveMaximum</li></ul></td><td><pre><code>{
  "type": "number",
  "minimum": 0,
  "exclusiveMaximum": 100
}
</code></pre></td><td><pre><code>// Положительный кейс 
{ 0 } или { 99 } или { 10 }

// Отрицательный кейс
{ 100 } или { -1 } </code></pre></td></tr><tr><td>multipleOf</td><td>Кратность числа number можно ограничивать с помощью multipleOf</td><td><pre><code>{
"type": "number",
"multipleOf" : 10
} </code></pre></td><td><pre><code>// Положительный кейс
{ 10 } или { 20 }

// Отрицательный кейс
{ 23 } </code></pre></td></tr></tbody></table>

### `Тип данных: "type": "object"`

<table data-full-width="true"><thead><tr><th width="130">Keywords</th><th width="204">Описание</th><th width="341">Пример JSON Shema</th><th>Примеры JSON сообщения</th></tr></thead><tbody><tr><td>properties</td><td>Тип данных объектов object можно ограничивать с помощью properties в котором прописаны ограничения для каждого объекта</td><td><pre><code>{
  "type": "object",
  "properties": {
    "number": { "type": "number" },
    "street_name": { "type": "string" },
    "street_type": { "enum": ["Street", "Avenue", "Boulevard"] }
  }
}
</code></pre></td><td><pre><code>// Положительный кейс 
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }

// Отрицательный кейс
{ "number": "1600", "street\_name": "Pennsylvania", "street\_type": "Avenue" } </code></pre></td></tr><tr><td>patternProperties</td><td>Тип данных объектов object можно ограничивать с помощью шаблонов свойств </td><td><pre><code>{
"type": "object",
"patternProperties": {
"^S\_": { "type": "string" },
"^I\_": { "type": "integer" }
}
} </code></pre></td><td><pre><code>// Положительный кейс
{ "S\_25": "This is a string" }
{ "I\_0": 42 }

// Отрицательный кейс
{ "S\_0": 42 } </code></pre></td></tr><tr><td>additionalProperties </td><td>Используется для управления обработкой дополнительных элементов, не входящих ни в properties, ни в patternProperties</td><td><pre><code>{
"type": "object",
"properties": {
"number": { "type": "number" },
"street\_name": { "type": "string" },
"street\_type": { "enum": \["Street", "Avenue", "Boulevard"] }
},
"additionalProperties": false
} </code></pre></td><td><pre><code>// Положительный кейс
{ "number": 1600, "street\_name": "Pennsylvania", "street\_type": "Avenue" }

// Отрицательный кейс
{ "number": 1600, "street\_name": "Pennsylvania", "street\_type": "Avenue", "direction": "NW" } </code></pre></td></tr><tr><td>required</td><td>Ограничение  на  обязательные объекты object</td><td><pre><code> {
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"address": { "type": "string" },
"telephone": { "type": "string" }
},
"required": \["name", "email"]
} </code></pre></td><td><pre><code>// Положительный кейс
{
"name": "William",
"email": "<bill@stratford.co.uk>",
"address": "Henley Street,England",
"telephone": "1234"
}

// Отрицательный кейс
{
"name": "William",
"address": "Henley Street,England"
} </code></pre></td></tr><tr><td>propertyNames</td><td>Формат элементов объекта object можно ограничивать с помощью ключевого слова propertyNames. Паттерн задается с помощью регулярного выражения RegEx</td><td><pre><code>{
"type": "object",
"propertyNames": {
"pattern": "^\[A-Za-z\_]\[A-Za-z0-9\_]\*$"
}
} </code></pre></td><td><pre><code>// Положительный кейс
{ "\_a\_proper\_token\_001": "value" }

// Отрицательный кейс
{ "001 invalid": "value" } </code></pre></td></tr><tr><td>minProperties<br>maxProperties</td><td>Количество свойств объекта можно ограничить с помощью ключевых слов</td><td><pre><code>{
"type": "object",
"minProperties": 2,
"maxProperties": 3
} </code></pre></td><td><pre><code>// Положительный кейс
{ "a": 0, "b": 1 }

// Отрицательный кейс
{ "a": 0 } </code></pre></td></tr></tbody></table>

### `Тип данных: "type": "array"`

<table data-full-width="true"><thead><tr><th width="184">Keywords</th><th width="240">Описание</th><th>Пример JSON Shema</th><th>Примеры JSON сообщения</th></tr></thead><tbody><tr><td>items </td><td>Ограничение на тип элементов массива (для всего массива)</td><td><pre><code>{
  "type": "array",
  "items": {
    "type": "number"
  }
}
</code></pre></td><td><pre><code>// Положительный кейс 
[1, 2, 3, 4, 5]

// Отрицательный кейс
\[1, 2, "3", 4, 5] </code></pre></td></tr><tr><td>prefixItems</td><td>Ограничение на тип элементов массива (для каждого конкретного индекса массива)</td><td><pre><code>{
"type": "array",
"prefixItems": \[
{ "type": "number" },
{ "type": "string" },
{ "enum": \["Street", "Avenue", "Boulevard"] },
{ "enum": \["NW", "NE", "SW", "SE"] }
]
} </code></pre></td><td><pre><code>// Положительный кейс
\[1600, "Pennsylvania", "Avenue", "NW"]

// Отрицательный кейс
\[1600, "Pennsylvania", "Avenue", "MOSCOW"] </code></pre></td></tr><tr><td>contains</td><td>Ограничение на содержание элемента в массиве</td><td><pre><code>{
"type": "array",
"contains": {
"type": "number"
}
} </code></pre></td><td><pre><code>// Положительный кейс
\["life", "universe", "everything", 42]

// Отрицательный кейс
\["life", "universe", "everything", "forty-two"] </code></pre></td></tr><tr><td>minItems<br>maxItems</td><td>Ограничение на длину массива </td><td><pre><code>{
"type": "array",
"minItems": 2,
"maxItems": 3
} </code></pre></td><td><pre><code>// Положительный кейс
\[1, 2]

// Отрицательный кейс
\[1, 2, 3, 4] </code></pre></td></tr></tbody></table>

## Пример&#x20;

<table data-full-width="true"><thead><tr><th width="196">Поле</th><th></th><th>Тип</th><th>Обязательность</th><th>Описание </th></tr></thead><tbody><tr><td>time</td><td></td><td><p>string</p><p>"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}(:[0-9]{2}(\\\\.[0-9]{6})?((-|\\\\+)[0-9]{2}:[0-9]{2})?)?)?$"</p></td><td>Да</td><td>Дата и время сообщения</td></tr><tr><td>eventId</td><td></td><td>string (255)</td><td>Да</td><td>Уникальный идентификатор события</td></tr><tr><td>contactID</td><td></td><td>string (255)</td><td>Да</td><td>Идентификатор контакта</td></tr><tr><td>operationType</td><td></td><td>string (enum)</td><td>Да</td><td>Тип операции<br>CREATE, READ, UPDATE, DELETE</td></tr><tr><td>getFlag</td><td></td><td>string (1)</td><td>Да</td><td>Флаг</td></tr><tr><td>phoneNumber</td><td></td><td><p>string (50)</p><p>pattern: "^([0-9]{10})$"</p></td><td>Да</td><td>Номер телефона клиента</td></tr><tr><td>phoneNumberTimeZone</td><td></td><td>string (255)</td><td>Да</td><td>Таймзона клиента</td></tr><tr><td>scenarioId</td><td></td><td>string (255)</td><td>Да</td><td>Номер сценария</td></tr><tr><td>customAttributeList</td><td></td><td>Array [Object]</td><td>Да</td><td></td></tr><tr><td></td><td>attributeName</td><td>string (255)</td><td>Да</td><td>Идентификатор атрибута<br>cardNum, lockSum, lockCurrency, lockDate</td></tr><tr><td></td><td>attributeValue</td><td>string (255)</td><td>Да</td><td>Значение атрибута</td></tr></tbody></table>

<details>

<summary>Большой развернутый пример</summary>

```json
{    
    "$schema":"http://json-schema.org/draft-06/schema#",
    "$ref":"#/definitions/test",
    "description": "Тестовое описание",
    "type": "object",
    "properties": {
      "time": {
        "type": "string",
        "description": "Дата и время сообщения",
        "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}(:[0-9]{2}(\\\\.[0-9]{6})?((-|\\\\+)[0-9]{2}:[0-9]{2})?)?)?$"
      },
      "eventId": {
        "type": "string",
        "description": "Уникальный идентификатор события",
        "minLength": 1,
        "maxLength": 255
      },
      "contactID": {
        "type": "string",
        "description": "Идентификатор контакта",
        "minLength": 1,
        "maxLength": 255
      },
      "operationType": {
        "type": "string",
        "description": "Тип операции",
	"enum": ["CREATE", "READ", "UPDATE", "DELETE"]
      },
      "getFlag": {
        "type": "string",
        "description": "Флаг",
	"maxLength": 1
      },
      "phoneNumber": {
        "type": "string",
        "description": "Номер телефона клиента",
        "pattern": "^([0-9]{10})$",
        "minLength": 1,
	"maxLength": 50
      },
      "phoneNumberTimeZone": {
        "type": "string",
        "description": "Таймзона клиента",
        "minLength": 1,
	"maxLength": 255
      },
      "scenarioId": {
        "type": "string",
        "description": "Номер сценария",
        "minLength": 1,
	"maxLength": 255
      },
      "customAttributeList": {
        "type": "array",
	"items": {
		"type": "object",
		"properties": {
			"attributeName": {
				"type": "string",
				"description": "Идентификатор атрибута",
				"minLength": 1,
				"maxLength": 255,
				"enum": ["cardNum", "lockSum", "lockCurrency", "lockDate"]
				},
			"attributeValue": {
				"type": "string",
				"description": "Значение атрибута",
				"minLength": 1,
				"maxLength": 255
				}
			},	
		"additionalProperties": false,
		"required":[
			"attributeName",
			"attributeValue"
			]
               }
      }
    },
"additionalProperties": false,
"required": [
	"time",
	"eventId",
	"contactID",
	"operationType",
	"getFlag",
	"phoneNumber",
	"phoneNumberTimeZone",
	"scenarioId",
	"customAttributeList"
    ]
}
```

</details>

Источники:&#x20;

* <https://infostart.ru/1c/articles/1543922/>
* Подробнее про JSON Shema: <https://infostart.ru/1c/articles/1546672/>
* Конвертер: <https://www.liquid-technologies.com/online-json-to-schema-converter>


# AVRO

{% hint style="info" %}
**AVRO** — это система сериализации (превращение объектов в массив байтов) данных, которая используется для работы с объектами в потоковой (распределенной) среде.&#x20;
{% endhint %}

AVRO является кроссплатформенной (не зависит от операционной системы и вида аппаратных ресурсов) системой, которая не зависит от языка программирования. Авро использует систему, основанную на схемах входных данных. Схемы могут включать в себя тип данных, структуру данных, формат записи данных, а также параметры их передачи (например, URL, порт и т.д.). Схемы AVRO описываются c помощью JSON-формата (JavaScript Object Notation), что обеспечивает AVRO независимость от языковой реализации. Для работы с Kafka используется специальный реестр схем (Schema Registry), который хранит в себе все схемы записей, использующихся брокером в данный момент времени.

Источник: <https://kafka-school.ru/blogs/kafka-avro/>


# JSON vs XML

<details>

<summary>Примеры JSON и XML</summary>

```json
JSON

{"Geeks":[ 
    { "firstName":"Vivek", "lastName":"Kothari" }, 
    { "firstName":"Suraj", "lastName":"Kumar" }, 
    { "firstName":"John", "lastName":"Smith" }, 
    { "firstName":"Peter", "lastName":"Gregory" } 
]}
```

```xml
XML

<Geeks> 
    <Geek> 
        <firstName>Vivek</firstName> <lastName>Kothari</lastName> 
    </Geek> 
    <Geek> 
        <firstName>Suraj</firstName> <lastName>Kumar</lastName> 
    </Geek> 
    <Geek> 
        <firstName>John</firstName> <lastName>Smith</lastName> 
    </Geek> 
    <Geek> 
        <firstName>Peter</firstName> <lastName>Gregory</lastName> 
    </Geek> 
</Geeks>
```

</details>

| JSON                                             | XML                                                                                                                          |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| Это просто формат, написанный на JavaScript      | Это язык разметки, который использует структуру тегов для представления элементов данных                                     |
| Данные хранятся как карта с парами ключ-значение | Данные XML хранятся в виде древовидной структуры                                                                             |
| Не использует закрывающий тег                    | Имеет начальный и конечный теги                                                                                              |
| Имеет меньший размер файлов                      | Имеет больший размер файлов                                                                                                  |
| Файлы очень легко читать по сравнению с XML      | Файлы трудно читать и интерпретировать                                                                                       |
| Менее защищен                                    | Более безопасен, чем JSON                                                                                                    |
| Не поддерживает комментарии                      | <p>Поддерживает комментарии<br>< !--Your comment-- ></p>                                                                     |
| Поддерживает массив                              | Не поддерживает массивы напрямую. Чтобы иметь возможность использовать массив, необходимо добавить теги для каждого элемента |

Источники:&#x20;

* <https://hackr.io/blog/json-vs-xml>
* <https://www.geeksforgeeks.org/difference-between-json-and-xml/>


# Виды интеграций

{% hint style="info" %}
**Интеграция** — это объединение разных систем и элементов в единую среду.
{% endhint %}

## Способы межсистемного взаимодействия

1. Синхронное взаимодействие
   1. REST
   2. SOAP
2. Асинхронное взаимодействие
   1. Kafka
   2. Rabbit MQ
   3. Другое (файловый обмен, база к базе)

Источники:&#x20;

* <https://habr.com/ru/companies/itq_group/articles/705598/>
* <https://habr.com/ru/articles/676088/>


# Синхронное взаимодействие

{% hint style="info" %}
**Cинхронное взаимодействие** — это способ организации взаимодействия между компонентами программной системы, при котором клиент, отослав запрос, блокируется и может продолжать работу только после получения ответа от сервера.
{% endhint %}

<figure><img src="/files/uJBGlzbheJM8LlDC0g5C" alt="" width="563"><figcaption><p>Синхронное взаимодействие</p></figcaption></figure>

## API

{% hint style="info" %}
**API (Application Programming Interface)** — это набор правил, которые позволяют двум приложениям или системам взаимодействовать друг с другом. Он определяет, каким образом программы могут обмениваться данными, запрашивать услуги и взаимодействовать с другими сервисами. API позволяет разным программам работать вместе, как если бы они были частью одного целого.
{% endhint %}

## Виды API

&#x20;Всего есть 4 общепринятых типа построения API:

1. **SOAP (Simple Object Access Protocol)** — это протокол для обмена структурированными сообщениями между веб-сервисами. Он использует формат данных XML для кодирования сообщений. SOAP применяется в распределенных системах и веб-сервисах для взаимодействия между клиентами и серверами. Сегодня SOAP встречается не так часто, так как XML довольно громоздкий, а сама архитектура SOAP не гибкая.
2. **RPC (Remote Procedure Call) API** — это метод взаимодействия между компонентами распределенной системы, позволяющий вызывать функции на удаленном сервере, как будто они являются локальными. Формат данных в RPC может быть разным, включая XML, JSON и бинарные форматы. RPC API применяется в распределенных системах для обеспечения совместной работы между клиентами и серверами с минимальными задержками.
3. **WebSocket API** — это двунаправленный протокол связи, позволяющий установить постоянное соединение между клиентом и сервером для обмена данными в режиме реального времени. Формат данных в WebSocket может быть текстовым или бинарным, включая JSON, XML и другие. WebSocket API часто используется в веб-приложениях для обмена сообщениями между сервером и браузером пользователя, например, в онлайн-играх, чатах или приложениях для обмена данными в реальном времени.
4. **REST (Representational State Transfer) API** — это архитектурный стиль для разработки веб-сервисов, основанный на стандартных HTTP-методах и ресурсоориентированном подходе. Формат данных в REST API может быть разнообразным, включая JSON, XML и другие. REST API широко применяется в веб-приложениях и мобильных приложениях для обеспечения межсистемного взаимодействия и интеграции с различными сервисами и платформами.

Наибольшее распространение получил REST формат API, так как он наиболее прост для разработки и понятен для пользователей.

Источники:&#x20;

* <https://1cloud.ru/blog/intoduction_in_api_and_restapi>
* <http://js.programs.kodika.school/05_rest_api/>


# REST

Рой Филдинг

{% hint style="info" %}
**REST (Representational State Transfer)** — это программный архитектурный стиль, который определяет набор ограничений, которые будут использоваться для создания веб-сервисов.&#x20;
{% endhint %}

## RESTful принципы

* Клиент-серверная модель (client-server model).
* Отсутствие состояния (statelessness).
* Кэширование (cacheability).
* Единообразие интерфейса (uniform interface).
* Многоуровневая система (layered system).
* Код по требованию (code on demand) — необязательно.

Подробнее в главе: [RESTful принципы](/hard-skills/integracii/vidy-integracii/sinkhronnoe-vzaimodeistvie/rest/restful-principy)

## RESTful Web Service

1. REST API работает поверх HTTP(S)-протокола и максимально эффективно использует его свойства.&#x20;

<details>

<summary>HTTP</summary>

**HTTP (HyperText Transfer Protocol)** — протокол прикладного уровня. Обмен сообщениями идёт по схеме «запрос-ответ». Для идентификации ресурсов HTTP использует глобальные URI. В отличие от многих других протоколов, HTTP не сохраняет своего состояния. Это означает отсутствие сохранения промежуточного состояния между парами «запрос-ответ». Компоненты, использующие HTTP, могут самостоятельно осуществлять сохранение информации о состоянии, связанной с последними запросами и ответами (например, «куки» на стороне клиента, «сессии» на стороне сервера).

Подробнее в главе HTTP: [HTTP](/hard-skills/devops-for-sa/osnovy-setei/http)

</details>

2. Веб-сервисы, соответствующие архитектурному стилю REST, которые называются RESTful Web-сервисами (RWS), обеспечивают взаимодействие между компьютерными системами в Интернете. Веб-сервисы RESTful позволяют запрашивающим системам получать доступ к текстовым представлениям веб-ресурсов и манипулировать ими с помощью унифицированного и предварительно определенного набора операций без сохранения состояния.

{% hint style="success" %}
HTTP (протокол) — REST API (стиль) — RESTful Web Service (RWS) (сервис)

Сервис RWS использует архитектурный стиль REST API, который использует протокол HTTP.&#x20;
{% endhint %}

Источники:&#x20;

* <https://1cloud.ru/blog/intoduction_in_api_and_restapi>
* <http://js.programs.kodika.school/05_rest_api/>


# RESTful принципы

## 1. Клиент-серверная модель (client-server model)

Клиент и сервер могут работать абсолютно независимо друг от друга. Разработчики используют достаточно простой способ организации REST API: клиентский код остается на его стороне, а код доступа — на сервере. Если клиентский код изменится, это не скажется на работе сервера, и наоборот. Благодаря этому REST API имеет такие преимущества, как переносимость и гибкость, а также возможность масштабирования.

## 2. Отсутствие состояния (statelessness)

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

## 3. Кэширование (cacheability)

В REST API запросах определяется, нужно ли кэшировать данные в буфере. Клиенту это дает высокую производительность и увеличивает скорость загрузки страниц, а серверу дает большие возможности масштабирования.

## 4. Единообразие интерфейса (uniform interface)

Одним из важнейших аспектов проектирования RESTful API является соблюдение единого интерфейса. Это предполагает использование согласованных соглашений и стандартных методов HTTP для обработки запросов API. Соответствуя этим стандартам, разработчики могут значительно упростить внедрение и обслуживание API. API REST должны использовать следующие стандартные методы HTTP для различных действий:

* `GET` : извлекает ресурс или коллекцию ресурсов.
* `POST` : Создает новый ресурс или отправляет данные для обработки.
* `PUT` : полностью обновляет существующий ресурс, заменяя его новыми данными.
* `PATCH` : Частично обновляет ресурс с определенными изменениями.
* `DELETE` : Удаляет ресурс.

Эти стандартные методы четко понимают каждую операцию и способствуют совместимости между клиентами и серверами. Для обеспечения надежной и последовательной работы крайне важно обеспечить правильный метод для каждого действия. Более того, единый интерфейс упрощает обработку ошибок и кодов состояния, гарантируя клиентам четкую и последовательную обратную связь. При создании RESTful API крайне важно возвращать точные и информативные коды состояния HTTP.  [Статусов много](https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F_HTTP), поэтому их всех не перечислить, однако важно знать их группировку::

* **2xx – Успех:** запрос был успешно получен, понят и принят.
* **3xx — Перенаправление (редирект):** запрос должен выполнить дальнейшие действия для завершения запроса.
* **4xx — Ошибка клиента:** запрос имеет неверный синтаксис или не может быть выполнен.
* **5xx — Ошибка сервера:** серверу не удалось выполнить кажущийся действительным запрос.

## 5. Многоуровневая система (layered system)

В RESTful возможна группировка серверов на разных уровнях, каждый из которых выполняет определенный функционал и выступает посредником между клиентом и сервером.

## 6. Код по требованию (code on demand) — необязательно

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

Источники:

* <https://gb.ru/blog/rest-api/>&#x20;
* <https://appmaster.io/ru/blog/shest-pravil-otdykha-apis> (подробнее)


# Отсутствие состояния (Авторизация)

> для справки: [Идентификация/Аутентификация/Авторизация](/hard-skills/qa-for-sa/identifikaciya-autentifikaciya-avtorizaciya)

## **Базовая аутентификация (Basic access authentication)**

Наиболее простая схема, при которой username и password пользователя передаются в заголовке Authorization в незашифрованном виде, а в закодированном (base64-encoded).

Обратите внимание, что даже несмотря на то, что ваши учетные данные закодированы, они не зашифрованы! Получить имя пользователя и пароль при базовой аутентификации очень просто. Не используйте эту схему аутентификации на обычном HTTP, а только при использовании HTTPS (HTTP через SSL/TLS).

Запрос при базовой аутентификации выглядит следующим образом:

```
GET / HTTP/1.1
Host: example.org
Authorization: Basic Zm9vOmJhcg==
```

В этом запросе закодированная пара *username:password (Zm9vOmJhcg==)* передаётся в заголовке Authorization.\
Базовая аутентификация HTTP редко рекомендуется из-за присущих ей уязвимостей безопасности.

## **Дайджест-аутентификация (Digest access authentication)**

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

При этой схеме сервер посылает уникальное значение *nonce*, а браузер передает MD5 хэш пароля пользователя, вычисленный с использованием указанного *nonce*.

<details>

<summary>Без аутентификации</summary>

Запрос клиента (без аутентификации)

<pre><code><strong>GET /dir/index.html HTTP/1.0
</strong>Host: localhost
</code></pre>

Ответ сервера (без аутентификации)

```
HTTP/1.0 401 Unauthorized
Server: HTTPd/0.9
Date: Sun, 10 Apr 2005 20:26:47 GMT
WWW-Authenticate: Digest realm="testrealm@host.com",
                       qop="auth,auth-int",
                       nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                       opaque="5ccc069c403ebaf9f0171e9517f40e41"
Content-Type: text/html
Content-Length: 311
```

</details>

<details>

<summary>С аутентификацией (имя пользователя «Mufasa», пароль «Circle Of Life»)</summary>

Запрос клиента

```markup
GET /dir/index.html HTTP/1.0
Host: localhost
Authorization: Digest username="Mufasa",
                    realm="testrealm@host.com",
                    nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                    uri="/dir/index.html",
                    qop=auth,
                    nc=00000001,
                    cnonce="0a4f113b",
                    response="6629fae49393a05397450978507c4ef1",
                    opaque="5ccc069c403ebaf9f0171e9517f40e41"
```

Ответ сервера (без аутентификации)

```
HTTP/1.0 200 OK
Server: HTTPd/0.9
Date: Sun, 10 Apr 2005 20:27:03 GMT
Content-Type: text/html
Content-Length: 7984
```

</details>

## **API ключи (API Keys)**

Некоторые API используют API ключи для авторизации. API ключ – это длинная уникальная строка содержащая произвольный набор символов, по сути заменяющие собой комбинацию username/password.

В большинстве случаев, сервер генерирует ключи доступа по запросу пользователей, которые далее сохраняют эти ключи в клиентских приложениях. При создании ключа также возможно ограничить срок действия и уровень доступа, который получит клиентское приложение при аутентификации с помощью этого ключа. Этот ключ может быть отправлен как параметр запроса&#x20;

```
GET /something?api_key=abcdef12345
```

или как заголовок

```
GET /something HTTP/1.1
X-API-Key: abcdef12345
```

или как cookie

```
GET /something HTTP/1.1
Cookie: X-API-KEY=abcdef12345
```

API ключи предполагаются быть секретными, т.е. только клиент и сервер знают этот ключ. Поэтому, как и в базовой, аутентификацию с помощью API ключей следует использовать только вместе с другими механизмами безопасности, такими как HTTPS/SSL.

## **Bearer authentication (also called token authentication)**

Аутентификация на предъявителя (также называемая аутентификацией токена) - это схема проверки подлинности HTTP, которая включает токены безопасности, называемые токенами на предъявителя. Имя «Аутентификация на предъявителя» можно понимать как «предоставить доступ носителю этого токена». Токен-носитель - это загадочная строка, обычно генерируемая сервером в ответ на запрос входа в систему. Клиент должен отправить этот токен несколькими способами:

в заголовке авторизации&#x20;

```
GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM
```

в теле запроса

```
POST /resource HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
              access_token=mF_9.B5f-4.1JqM`
```

как параметр запроса

```
GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1
Host: server.example.com
```

Источники:

* <https://telegra.ph/Vidy-autentifikacii-v-REST-API-10-18-2>
* <https://blog.restcase.com/4-most-used-rest-api-authentication-methods/>


# OAuth / OpenID Connect


# Кеширование

{% hint style="info" %}
**Кэширование** — это возможность хранить копии часто используемых данных в нескольких местах по пути запроса-ответа.
{% endhint %}

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

## Зачем использовать кэширование?

* **Это сокращает время ответа:** когда клиент неоднократно инициирует API без инструкций по кэшированию, время ответа API остается одинаковым независимо от того, изменяются данные или нет. API с инструкциями по кэшированию ускоряет время ответа, поскольку первый запрос клиента сохраняется в кеше для будущих запросов. Пока срок действия данных не истек или не изменился, результаты API можно использовать снова и снова.
* **Это снижает нагрузку на сервер:** кэширование действует как промежуточное программное обеспечение между клиентом и сервером. Он перехватывает запрос от клиента и обрабатывает данные запроса. Если данные ответа находятся в кеше, клиент может получить данные без участия сервера.
* **Это повышает производительность вашего приложения**: поскольку сервер освобождается от повторной обработки кэшированных данных, вместо этого он может выполнять другие операции.

### Кеширование в REST

Кэшируемость — одно из архитектурных ограничений REST.

* **GET-** запросы должны кэшироваться по умолчанию — до тех пор, пока не возникнет особое условие. Обычно браузеры рассматривают все запросы GET как кэшируемые.
* **POST-** запросы не кэшируются по умолчанию, но их можно сделать кэшируемыми, если к ответу добавлен `Expires` заголовок или `Cache-Control`  заголовок с директивой, явно разрешающей кэширование.
* Ответы **PUT** и **DELETE** запросы вообще не кэшируются.

## Как управлять кешем

Ниже приведены основные заголовки HTTP-ответов, которые мы можем использовать для управления поведением кэширования:

### Expires

HTTP- заголовок `Expires` указывает до какого времени можно хранить ресурс в кэш. По истечении этого времени кэшированное представление считается устаревшим и должно быть повторно проверено на исходном сервере.

### Last-Modified

Заголовок `Last-Modified` указывает, когда связанный ресурс был последний раз изменен. Этот заголовок используется в качестве средства проверки, чтобы определить, совпадает ли полученный ответ сервера с ранее сохраненным ресурсом в кэше клиента.

### ETag

Заголовок `ETag` — это токе&#x43D;*,* который генерируется сервером на основе содержимого ресурса и позволяет однозначно идентифицировать его состояние. Если ресурс по данному URL-адресу изменяется,  сервер создет новый токен `Etag`. Сравенение старого и нового токена от сервера поможет определить, являются ли два ресурса одинаковыми и нужно ли обновлять кэш на клиенте.

### Cache-Control

Значение заголовка `Cache-Control` содержит одну или несколько директив, разделенных запятыми . Эти директивы определяют, кэшируется ли ответ, и если да, то кем и как долго, например, `max-age` или `s-maxage` директивы.

Например, если вы установите значение `Cache-Control` в заголовке ответа API на `max-age=60`, браузер будет хранить кэш в течение шестидесяти секунд.

## Инвалидация кеша

{% hint style="info" %}
**Инвалидация кэша** — это процесс, при котором компьютерная система объявляет записи кэша недействительными и удаляет или заменяет их. Если данные изменяются, они должны быть инвалидированы в кэше, в противном случае это может привести к несогласованному поведению приложения.
{% endhint %}

### Инвалидация по TTL

При сохранении данных  в кэш для них устанавливается время жизни (TTL - time to live) и данные будут автоматически удалены через это время.&#x20;

Основная проблема заключается в подборе TTL. Если TTL слишком короткий, то запись может “протухнуть” и стать недействительной раньше, чем обновление было бы необходимо, что приведет к отправке повторного запроса в источник данных. Если TTL слишком длинный, то запись может содержать устаревшие данные, что может привести к ошибкам или неправильной работе приложения. Обычно ответ на этот вопрос подбирается эмпирическим путем.

### Инвалидация по событию

При таком подходе данные инвалидируют при наступлении некого события – обычно это обновление данных в источнике. В качестве события для инвалидации данных может выступать время последней модификации данных. Такой способ используется в HTTP.

Источники:

* <https://stellate.co/blog/deep-dive-into-caching-rest-apis>
* <https://restfulapi.net/caching/>
* <https://ml-system-design.ru/courses/system-design/learn/2.7>
* <https://habr.com/ru/articles/734660/>


# Единообразие интерфейса (CRUD)

Операции в REST

RESTful API сводится к четырем базовым операциям [POST, GET, PUT и DELETE](#user-content-fn-1)[^1]:

<table><thead><tr><th width="147.33333333333331">Название</th><th width="139">HTTP</th><th>Описание</th></tr></thead><tbody><tr><td>Создание новых данных</td><td>POST</td><td>POST-запрос используется для создания нового ресурса на сервере. Он передает данные, которые должны быть использованы для создания нового ресурса. В отличие от PUT-запроса, POST-запрос не требует знания о существующих ресурсах и их идентификаторах.</td></tr><tr><td>Получение данных</td><td>GET</td><td>GET-запрос используется для получения информации от сервера. Он запрашивает данные от определенного ресурса и не вносит изменения на сервере. Примером может быть просмотр веб-страницы или получение данных из API.</td></tr><tr><td>Обновление данных</td><td>PUT</td><td>PUT-запрос используется для обновления существующих данных на сервере. Он требует передачи полного обновленного набора данных для указанного ресурса. Если ресурс не существует, сервер может создать его, в зависимости от реализации.<br><em>*Альтернатива: PATCH-запрос, частично обновляет ресурс с определенными изменениями.</em></td></tr><tr><td>Удаление данных</td><td>DELETE</td><td>DELETE-запрос используется для удаления указанного ресурса на сервере. Он не требует передачи дополнительных данных.</td></tr></tbody></table>

## Характеристики операций

### Безопасность

{% hint style="info" %}
Если операция может изменить ресурс — она называется **небезопасной** в рамках REST архитектуры.
{% endhint %}

GET, OPTIONS, HEAD — работают только на чтение, поэтому они безопасны для ресурса.

POST, PUT, DELETE — могут модифицировать данные, поэтому они небезопасные.

## Идемпотентность

{% hint style="info" %}
**Идемпотентная операция** — действие, многократное повторение которого эквивалентно однократному.
{% endhint %}

PUT, GET, OPTIONS, DELETE, HEAD — идемпотентные.

POST, PATCH — неидемпотентные.

Источники:

* <https://qsusha.wordpress.com/2017/10/29/%D1%8D%D1%82%D0%BE-%D1%81%D0%BC%D0%B5%D1%88%D0%BD%D0%BE%D0%B5-%D1%81%D0%BB%D0%BE%D0%B2%D0%BE-%D0%B8%D0%B4%D0%B5%D0%BC%D0%BF%D0%BE%D1%82%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9/>
* <https://stackoverflow.com/questions/45016234/what-is-idempotency-in-http-methods>

[^1]: По другому такое сочетание методов называется CRUD модель, где:\
    C — Create (POST)\
    R — Read (GET)\
    U — Update (PUT)\
    D — Delete (DELETE)


# Запрос/ответ

## Структура запроса

1. **Конечная точка (endpoint)** — адрес, по которому отправляется запрос.

Один и тот же объект (ресурс) может иметь несколько конечных точек.\
Например, чтобы отправить запрос на сервер службы доставки Best Delivery, может использоваться конечная точка `best-delivery.com/orders`. Чтобы посмотреть список заказов, можно использовать конечную точку `best-delivery.com/orders/list`, а чтобы разместить новый заказ — `best-delivery.com/orders/create`.

2. **Параметры** — делятся на параметры пути и параметры запроса.

Например, в запросе `best-delivery.com/orders/{userId}/list` `{userId}` — это параметр пути. Вместо `{userId}` нужно подставить идентификатор конкретного пользователя, тогда запрос вернет список заказов этого пользователя.\
В запросе `best-delivery.com/orders/list?orderId=123456` `orderId` — это параметр запроса. Такой запрос вернет информацию о конкретном заказе.\
В одном запросе может быть несколько параметров пути и несколько параметров запроса. Параметры запроса соединяются между собой символом &. Например, запрос `best-delivery.com/orders/shop/{shopId}/users/{userId}/list?top=10&sortDate=DESC` вернет список заказов в магазине `{shopId}` для пользователя `{userId}`, причем список будет содержать только 10 последних заказов, т.к. он отсортирован по убыванию даты заказа.

3. **Заголовки (headers)** — в заголовках определяется формат передаваемых данных, спецификация и версия протокола обмена и другая информация, необходимая для корректной обработки запроса.

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

4. **Тело запроса (body)** — данные для обработки, как правило в формате JSON.

Например, запрос для службы доставки может содержать номер заказа, адрес, телефон для связи и интервал доставки, примерно так:\
`{“orderId”:123456, “address”:”119021, Москва, ул. Льва Толстого, 16”, “phone”:”+74957397000”, “time_interval”:”9:00-11:00”}`.

## Структура ответа

После выполнения REST API запроса сервер вернет клиентскому приложению ответ. Он включает код ответа, заголовки и тело ответа.

* Как и в запросе, заголовки в ответе также определяют формат передаваемых данных, спецификацию и версию протокола обмена, и другие сведения, которые помогут клиентскому приложению правильно прочитать и понять ответ.
* Тело ответа — это информация, которую запрашивал клиент. Ответ тоже чаще всего передается в формате JSON. Но тело ответа может быть и пустым.
* Код ответа — это признак успешности выполнения запроса. Для унификации используются стандартные коды ответа. Они представляют собой трехзначные числа. Ответы, начинающиеся с цифры 1, обозначаются 1xx, и т.п.

Ответы вида 1хх — информационные.

Ответы вида 2хх говорят об успешном выполнении запроса. Например:

> 200 – ОК. Если клиентом были запрошены какие-либо данные, то они находятся в заголовке или теле сообщения.\
> 201 – OK. Создан новый ресурс.

Ответы вида 3xx обозначают перенаправление или необходимость уточнения. Например:

> 300 — на отправленный запрос есть несколько вариантов ответа. Чтобы получить нужный вариант, клиент должен уточнить запрос.\
> 301 — запрашиваемый адрес перемещен.\
> 307 — запрашиваемый адрес временно перемещен.

Ответы вида 4хх говорят о том, что при выполнении запроса возникла ошибка, и это ошибка на стороне клиента. Например:

> 400 – Bad Request. Запрос некорректный.\
> 401 – Unauthorized. Запрос требует аутентификации пользователя.\
> 403 – Forbidden. Доступ к сервису запрещен.\
> 404 – Not found. Ресурс не найден.

Ответы вида 5хх говорят об ошибке на стороне сервера. Например:

> 503 — сервис недоступен.\
> 504 — таймаут (превышено допустимое время обработки запроса).

Источник:

* <https://cloud.yandex.ru/ru/docs/glossary/rest-api>


# Cтепень зрелости REST API

## Уровень 0: Собачье болото (The Swamp of POX)

В википедии данный уровень зрелости называется болотом оспы, но мне такое название не очень нравится(звучит противно), поэтому добавим немного поэзии и переведем **The Swamp of Plain Old XML**, как болото Простого Старого Ыксемеля, что сокращенное читается, как ПСЫ, а значит собачье.

Вообще, данный уровень нулевой потому, что систему, данного уровня вообще нельзя классифицировать, как **RESTful**.

В такой реализации у нас есть один **URL**, на который поступают все запросы (обычно **POST**) и система уже по составу запроса решает, что от нее хотят и какой ей дать на это ответ.

Однако, даже для такого спорного уровня зрелости существуют свои правила:

* **В URL адресах должны использоваться дефисы** **(-)**, чтобы улучшить их читаемость. Это значит, что при составлении адресов должен использоваться spinal-case.

  Пример:

  <http://api.example.com/blogs/guy-levin/posts/this-is-my-first-post> - хорошо

  <http://api.example.com/blogs/guylevin/posts/thisismyfirstpost> - плохо
* **Не должны использоваться нижние подчеркивания** **(\_)**

  Тут все очевидно – смотрим правило 1
* Предпочтительно использовать строчные буквы при составлении URL адресов

  Тут тоже все понятно:

  <http://api.example.com/my-folder/my-doc> - хорошо

  <http://api.example.com/My-Folder/my-doc> - плохо
* В URL нельзя включать расширения файлов

  Это значит, что когда мы хотим получить какой-либо файл с сервера, то мы не указываем его расширение:

  <http://api.college.com/student/3248234/course/2005/fall> - хорошо

  <http://api.college.com/student/3248234/course/2005/fall.json> - плохо

## РАСПИСАТЬ ДАЛЬШЕ&#x20;

Источник: <https://habr.com/ru/companies/itq_group/articles/705598/>

<https://habr.com/ru/articles/590679/> (новая)


# Проектирование API

<figure><img src="/files/VKj8OAaDK4rXb5b6CrYp" alt=""><figcaption><p>UML диаграмма вызова REST API для use-case "Добавить новый товар"</p></figcaption></figure>

Источник:&#x20;

* <https://babok-school.ru/blog/authentication-vs-authorization-in-web-api-and-postman/>


# Асинхронный REST

## Синхронный (классический) REST

<div align="center"><figure><img src="/files/wAExBCHHpNIswFmGQCqD" alt="" width="323"><figcaption><p>Синхронный REST</p></figcaption></figure></div>

<figure><img src="/files/ie87PWyYeIyO5vlVGLRb" alt="" width="364"><figcaption><p>Пример синхронного REST</p></figcaption></figure>

## Асинхронный REST

### Запрос

<figure><img src="/files/FfDwS4mAvFtilszQzlZT" alt="" width="375"><figcaption><p>Пример асинхронного запроса REST, где сервер возвращает код 202 - "принято"</p></figcaption></figure>

### Ответ Callback (обратный вызов)

<figure><img src="/files/9W60Xx3w8XIdOK1mahav" alt="" width="360"><figcaption><p>Пример асинхронного ответа REST, где сервер сам инициирует ответ с помощью callback</p></figcaption></figure>

### Ответ в цикле (прямой вызов)

<figure><img src="/files/zlw8qTCocJaxuFOUa13N" alt="" width="365"><figcaption><p>Пример асинхронного ответа REST, где клиент инициирует ответ с помощью цикличного обращения к серверу</p></figcaption></figure>

Источник: <https://www.youtube.com/watch?v=3D2kYmEa8rk&ab_channel=%D0%90%D0%B9%D1%82%D0%B8%D0%AD%D0%BA%D1%81%D0%BF%D1%80%D0%B5%D1%81%D1%81>


# SOAP

{% hint style="info" %}
**SOAP** — это протокол, по которому веб-сервисы взаимодействуют друг с другом или с клиентами. Название происходит от сокращения Simple Object Access Protocol («простой протокол доступа к объектам»).&#x20;

SOAP API — это веб-сервис, использующий протокол SOAP для обмена сообщениями между серверами и клиентами. При этом сообщения должны быть написаны на языке XML в соответствии со строгими стандартами [WSDL](/hard-skills/integracii/vidy-integracii/sinkhronnoe-vzaimodeistvie/soap/wsdl), иначе сервер вернет ошибку.
{% endhint %}

## **Структура SOAP запроса**

### **Envelope («конверт»)**

Это корневой элемент. Определяет XML-документ как сообщение SOAP с помощью пространства имен xmlns:soap=»<http://www.w3.org/2003/05/soap-envelope/»>. Если в определении будет указан другой адрес, сервер вернет ошибку.

### **Header («заголовок»)**

Включает в себя атрибуты сообщения, связанные с конкретным приложением (аутентификация, проведение платежей и так далее). В заголовке могут использоваться три атрибута, которые указывают, как принимающая сторона должна обрабатывать сообщение, — **mustUnderstand**, **actor** и **encodingStyle.** Значение **mustUnderstand** — 1 или 0 — говорит принимающему приложению о том, следует ли распознавать заголовок в обязательном или опциональном порядке. Атрибут **actor** задает конкретную конечную точку для сообщения. Атрибут **encodingStyle** устанавливает специфическую кодировку для элемента. По умолчанию SOAP-сообщение не имеет определенной кодировки.

### **Body («тело»)**

Сообщение, которое передает веб-приложение. Может содержать запрос к серверу или ответ от него.

<details>

<summary>Пример запрос/ответа XML</summary>

*Пример сообщения, которое запрашивает стоимость ноутбука в онлайн-магазине:*

```xml
<?xml version="1.0"?>
<soap:Envelope
	xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
	soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body> 
	<m:GetPrice xmlns:m="https://online-shop.ru/prices">
		<m:Item>Dell Vostro 3515-5371</m:Item>
	</m:GetPrice>
</soap:Body>
</soap:Envelope>
```

*Пример ответа сервера онлайн-магазина:*

```xml
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
	soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body>
	<m:GetPriceResponse xmlns:m="https://online-shop.ru/prices">
		<m:Price>37299</m:Price>
	</m:GetPriceResponse>
</soap:Body>
</soap:Envelope>
```

</details>

### **Fault («ошибка»)**

Опциональный элемент. Передает уведомление об ошибках, если они возникли в ходе обработки сообщения. Может содержать вложенные элементы, которые проясняют причину возникновения ошибки:

* **faultcode** — код неполадки;
* **faultstring** — «человекопонятное» описание проблемы;
* **faultactor** — информация о программном компоненте, который вызвал ошибку;
* **detail** — дополнительные сведения о месте возникновения неполадки.

## В каких случаях используют SOAP <a href="#v-kakikh-sluchayakh-ispolzuyut-soap" id="v-kakikh-sluchayakh-ispolzuyut-soap"></a>

* **В интеграции сложных систем.** SOAP поддерживает передачу сложных объектов и атрибутов, что позволяет эффективно обмениваться данными между системами.
* **Когда есть необходимость в строгих стандартах безопасности с поддержкой SSL.** SOAP API использует WS-Security для обеспечения безопасности приложений на уровне предприятия и для связи с унаследованными системами.
* **Когда нужны надежные функции обмена сообщениями.** Если вам необходимо гарантировать, что сообщения будут доставлены в надежном порядке и без потерь, то SOAP API обеспечит надежную доставку сообщений между системами при помощи расширения WS-ReliableMessaging.
* **Когда необходимо сохранить конфиденциальность.** SOAP API включает в себя соответствие стандарту ACID (Atomicity, Consistency, Isolation, and Durability) и это соответствие уменьшает избыточность и повышает безопасность и целостность сообщений.

### Недостатки SOAP <a href="#d0-bd-d0-b5-d0-b4-d0-be-d1-81-d1-82-d0-b0-d1-82-d0-ba-d0-b8-soap" id="d0-bd-d0-b5-d0-b4-d0-be-d1-81-d1-82-d0-b0-d1-82-d0-ba-d0-b8-soap"></a>

* **Объемные сообщения:** SOAP API использует XML для сериализации данных, что приводит к увеличению объема передаваемых сообщений. Проблемы возникают при передаче больших объемов данных или при работе с медленными сетевыми соединениями.
* **Поддержка только одного формата:** SOAP API ограничен использованием только XML в качестве формата данных. В некоторых случаях это может означать дополнительные накладные расходы на преобразование данных из других форматов в XML и обратно.
* **Один запрос — один ответ (один end-point):** клиент должен отправить запрос и дождаться ответа от сервера, прежде чем продолжить выполнение следующих операций. Это может привести к блокировке клиентского приложения, если запрос долго обрабатывается.
* **Возможность нарушения работы клиента при смене описания веб-сервиса:** смена описания потребует дополнительных усилий для согласования изменений между поставщиком и потребителем сервиса.

Источники:&#x20;

* <https://habr.com/ru/companies/itq_group/articles/705598/>
* <https://blog.skillfactory.ru/glossary/soap-api/>
* <https://elbrusboot.camp/blog/soap-api/>


# XSD

XML Schema

{% hint style="info" %}
**XSD (Xml Schema Definition)** — это язык описания структуры XML документа. Его также называют XML Schema. При использовании XML Schema XML парсер может проверить не только правильность синтаксиса XML документа, но также его структуру, модель содержания и типы данных.
{% endhint %}

Такой подход позволяет объектно-ориентированным языкам программирования легко создавать объекты в памяти, что, несомненно, удобнее, чем разбирать XML как обычный текстовый файл.

## Структура

Документ XSD начинается с корневого элемента `schema`. Каждый тег в XML-документе определяется с помощью тега `element`. Каждый из этих элементов может содержать простое содержимое (например, строку или дату) или более сложные данные (например, вложенные элементы).

**Например:** вы пишете XSD для XML-документа, описывающего клиента. В XSD вы можете объявить, что у Клиента должен быть 1 адрес и что каждый адрес должен содержать состояние, но почтовый индекс не является обязательным:

<details>

<summary>Простой пример XML</summary>

```xml
<Customer>
  <Name>Bob Carolgees</Name>
  <Address>
    <Street>1 Homer Street</Street>
    <City>Flanville</City>
    <State>BZ</State>
    <Country>DE</Country>
  </Address>
</Customer>
```

</details>

<details>

<summary>Простой пример XSD</summary>

```xml
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <xsd:element name="Customer" type="CustomerType"/>

  <xsd:complexType name="CustomerType">
    <xsd:sequence>
      <xsd:element name="Name" type="xsd:string"/>
      <xsd:element name="Address" type="AddressType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="AddressType">
    <xsd:sequence>
      <xsd:element name="Street" type="xsd:string"/>
      <xsd:element name="City" type="xsd:string"/>
      <xsd:element name="State" type="xsd:string"/>
      <xsd:element name="ZipCode" type="xsd:string" minOccurs="0"/>
      <xsd:element name="Country" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>

</xsd:schema>
```

</details>

Источники:

* <https://habr.com/ru/articles/90696/>
* <https://www.tutorialworks.com/xsd-vs-wsdl/>


# WSDL

XML "Swagger"

{% hint style="info" %}
**WSDL (Web Services Description Language)** — это язык описания веб-сервисов, основанный на XML. На нем описываются методы, входные и результирующие структуры данных, типы данных, сетевые адреса для обращения к сервису и другое.

SOAP связан с WSDL по той части, что SOAP обеспечивает транспорт, а WSDL обеспечивает объявление веб-сервиса.
{% endhint %}

## Элементы WSDL

Существуют две версии языка:

* версия 1.1 от 2001 года, <https://www.w3.org/TR/wsdl.html>
* версия 2.0 от 2007 года, <https://www.w3.org/TR/wsdl/>

Документы WSDL состоят из следующих разделов:

<table data-full-width="true"><thead><tr><th>Раздел</th><th>Версия 1.1</th><th>Версия 2.0</th></tr></thead><tbody><tr><td>&#x3C;definitions></td><td>Задает пространства имен для документа WSDL, XML-схемы и SOAP</td><td>Отсутствует.<br>Вместо него существует раздел &#x3C;description></td></tr><tr><td>&#x3C;description></td><td>Отсутствует.<br>Вместо него существует раздел &#x3C;definitions></td><td>Задает пространства имен для документов WSDL, XML и SOAP</td></tr><tr><td>&#x3C;types></td><td>Элементы (данные), с которыми работает веб-сервис</td><td>Аналогично</td></tr><tr><td>&#x3C;message></td><td>Сообщения, с которыми работает веб-сервис</td><td>Отсутствует</td></tr><tr><td>&#x3C;portType></td><td>Операции, которые могут проводиться с сообщениями из раздела &#x3C;message></td><td>Отсутствует. Вместо него существует раздел &#x3C;interface></td></tr><tr><td>&#x3C;interface></td><td>Отсутствует.<br>См. раздел &#x3C;portType></td><td>Операции, которые могут проводиться с элементами (данными) из раздела &#x3C;types></td></tr><tr><td>&#x3C;binding></td><td>Определение сетевого протокола и формат данных, используемых для операций из раздела &#x3C;portType></td><td>Аналогично</td></tr><tr><td>&#x3C;operation></td><td>Абстрактное определение операции (функции), в которой указываются входящее и исходящее сообщения, а так же сообщение об ошибке.</td><td>Аналогично</td></tr><tr><td>&#x3C;service></td><td>Объединяет конечные точки (адреса), реализующие общий интерфейс веб-сервиса. В разделе указывается общий адрес веб-сервиса</td><td>Аналогично</td></tr><tr><td>&#x3C;port></td><td>Протоколы и адреса, по которым выполняются запросы к веб-сервису</td><td>Отсутствует</td></tr><tr><td>&#x3C;endpoint></td><td>Отсутствует.<br>Вместо него существует раздел &#x3C;port></td><td>Протоколы и адреса, по которым выполняются запросы к веб-сервису</td></tr></tbody></table>

Источники:&#x20;

* <https://yandex.ru/dev/direct/doc/dg-v4/concepts/SOAP.html>
* <https://vbeg.ru/tezam/soap-i-wsdl-teoriya/>
* <https://systems.education/soap-integration> (подробнее)


# REST vs SOAP

мыло или отдых

<table><thead><tr><th width="163"></th><th>REST API</th><th>SOAP API</th></tr></thead><tbody><tr><td>Определение</td><td>Архитектурный стиль</td><td>Протокол</td></tr><tr><td>Формат данных</td><td>JSON</td><td>XML</td></tr><tr><td>Протокол</td><td>HTTP/HTTPS</td><td>HTTP/HTTPS, SMTP, XMPP, и другие</td></tr><tr><td>Описание интерфейса</td><td>Необязательно. <br>Часто используют OpenAPI (Swagger)</td><td>Обязательно. <br>Стандартизация с помощью WSDL (Web Services Description Language)</td></tr><tr><td>Сложность</td><td>Считается более простым и легковесным, поскольку он не требует сложных структур и форматов сообщений</td><td>Cложнее из-за использования XML, где сообщения состоят из заголовков (headers) и тела (body)</td></tr><tr><td>Состояния</td><td>RESTful архитектура является без состояния (stateless), что означает, что каждый запрос от клиента содержит всю необходимую информацию для его обработки</td><td>Может использовать состояние и сохранять контекст между запросами</td></tr><tr><td>Кеширование</td><td>Поддерживает хоршее кеширование на уровне HTTP</td><td>Обычно имеет ограниченную поддержку кеширования</td></tr><tr><td>Модель безопасности</td><td>Использует HTTPS для обеспечения безопасности. Также может использовать токены авторизации, как OAuth</td><td>Следует стандартам WS-Security для безопасности</td></tr><tr><td>Поддержка</td><td>Популярен в веб-приложениях и мобильных приложениях. Широко используется в RESTful веб-сервисах.</td><td>Имеет более широкую поддержку в старых системах и в предприятии.</td></tr></tbody></table>

Источники:&#x20;

* <https://habr.com/ru/companies/otus/articles/737610/>
* <https://blog.skillfactory.ru/glossary/soap-api/>


# Асинхронное взаимодействие

{% hint style="info" %}
**Асинхронное взаимодействие** — это способ организации взаимодействия между компонентами программной системы, при котором отправитель не блокируется и может продолжать выполнение других задач, в то время как операция выполняется или ожидает ответа от получателя. В асинхронной модели отправитель и получатель не ожидают непосредственного завершения операции, а вместо этого используют механизмы обратного вызова или уведомлений для обработки результатов операции, когда они станут доступны.
{% endhint %}

<figure><img src="/files/6uuo02BExwkb0LIYJZEa" alt="" width="563"><figcaption><p>Асинхронное взаимодействие</p></figcaption></figure>

## Варианты обмена информацией

При синхронном взаимодействии:&#x20;

* *Request-Response* (Запрос-Ответ)
* *One-Way* (Односторонний) или *Fire and Forget* (Отправил и забыл)

При асинхронном взаимодействии:&#x20;

* *Publish-Subscribe* (Публикация-Подписка) или сокращённо Pub-Sub
* *Point-to-Point* (Точка-Точка)

В паттернах Pub-Sub и Point-to-Point происходит асинхронное общение через посредника. При реализации таких паттернов у программ появляются возможности:

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

## Брокеры сообщений

{% hint style="info" %}
**Message broker** (брокер сообщений) — это промежуточное программное обеспечение, которое обеспечивает асинхронную коммуникацию между различными компонентами системы, позволяя им обмениваться сообщениями. Он служит посредником между отправителем (producer) и получателем (consumer) сообщений, обеспечивая надежную доставку сообщений даже в условиях различных технологических и временных ограничений.
{% endhint %}

Основные компоненты и функции, которые предоставляет message broker:

1. **Очередь сообщений и топик:** Брокер сообщений обеспечивает создание и управление очередью сообщений, где отправители помещают сообщения для последующей обработки или доставки получателям. Очередь гарантирует, что сообщения обрабатываются в порядке их поступления.
2. **Гарантия доставки:** Брокер сообщений обеспечивает надежную доставку сообщений получателям. Он может использовать различные механизмы, такие как подтверждения, переотправка и повторная обработка сообщений, чтобы убедиться, что сообщение будет доставлено, даже если получатель временно недоступен или система перегружена.
3. **Маршрутизация сообщений:** Брокер сообщений может выполнять функцию маршрутизации, определяя, какие сообщения должны быть доставлены конкретным получателям или группам получателей. Это позволяет гибко настраивать и управлять потоком сообщений.
4. **Преобразование сообщений:** Брокер сообщений может выполнять преобразование сообщений между различными форматами данных или протоколами, позволяя отправителям и получателям использовать разные форматы или интерфейсы.
5. **Управление подписками:** Брокер сообщений позволяет компонентам системы подписываться на определенные типы сообщений или каналы коммуникации. Это позволяет гибко настраивать поток сообщений и контролировать, какие компоненты получают какие сообщения.

### Очередь сообщений и топик

Брокер, реализующий шаблон Point-to-Point, ассоциируется с термином Queue (Очередь). Сообщения отправителя попадают в очередь, получатель извлекает сообщения из очереди. После извлечения сообщение становится больше никому не доступными. Данные в очереди хранятся, пока они не будут прочитаны или не истечёт срок их действия.

В Pub-Sub ассоциируется с темой, топиком (Topic). Сообщения попадают в топик. Система распределяет каждое сообщение между всеми подписчиками топика (Broadcast, вещание). Сообщения могут храниться в топике, до тех пор, пока это необходимо для распространения данных между всеми подписчиками.

### Гарантия доставки

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

* **At most once (Не более одного раза)**

  Самый простой вариант — отправка в стиле Fire and Forget (Отправил и забыл). Большая часть сообщений доходит до получателя, но часть теряется из-за сбоев.
* **At least once (Хотя бы один раз)**

  Чтобы все данные достигли цели, могут предприниматься повторные отправки. Хотя бы одна попытка будет успешной. В таком случае сообщения не теряются, но могут дублироваться.
* **Exactly once (Строго один раз)**

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

### Когда использовать брокеры?

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

Источники:&#x20;

* <https://testengineer.ru/message-broker/>
* <https://habr.com/ru/companies/innotech/articles/698838/>


# Kafka

«Тупой брокер, умный потребитель»

{% hint style="info" %}
**Apache Kafka** — программный Pub-Sub брокер с открытым исходным кодом. Помимо гарантий доставки At most once и At least once, поддерживает Exactly once (Строго один раз). Обычно используется в больших проектах, так как обладает большой пропускной способностью и отказоустойчивостью, превосходит по данным характеристикам RabbitMQ и многие другие брокеры. При этом имеет высокий порог вхождения, требователен к ресурсам.
{% endhint %}

Kafka можно представить, как распределённый, реплицируемый лог коммитов. Распределённый, так как он разворачивается в виде кластера нод (под управлением Apache Zookeeper). Реплицируемый, потому что все данные синхронизируются между нодами. Лог, входящие сообщения последовательно добавляются в журнал и остаются там неизменными, не удаляются при чтении, как это происходит в RabbitMQ.

## Принцип работы

<figure><img src="/files/sQZyKWS67AWchqwfLz1d" alt=""><figcaption><p>Схема работы Kafka</p></figcaption></figure>

В Kafka отсутствует понятие очереди (Queue), приложения пишут или читают сообщения из партиционированных топиков (Topic). Если просто, то принцип работы такой: приложение-продюсер (Producer) отправляет сообщение в топик брокера, которое записывается в конец одной из его партиций (Partition). По умолчанию для распределения сообщений между партициями топика используется алгоритм Round-Robin. Отправитель может влиять на выбор партиции, передавая вместе с сообщением специальный ключ (Message Key).

Приложения-подписчики (Consumer) читают, вытягивают (pull) сообщения из заданного топика. Для каждого подписчика Kafka запоминает указатель на последнее прочитанное им сообщение (offset). Если приложение падает, то восстановившись может продолжать чтение с прежнего места или перемотать (rewind) offset в прошлое и прочитать данные повторно.

Для Kafka принцип «Тупой брокер, умный потребитель» означает, что, в отличие от RabbitMQ, он не занимается контролем и распределением сообщений. Потребители сами опрашивают брокер и решают, какие сообщения им читать, брокер только хранит данные.

Источники:&#x20;

* <https://habr.com/ru/companies/innotech/articles/698838/>
* <https://habr.com/ru/companies/sbermarket/articles/738634/#arch> (почитать)


# RabbitMQ

«Умный брокер, тупой потребитель»

{% hint style="info" %}
**RabbitMQ** — традиционный брокер сообщений с открытым исходным кодом, работающий как автономно, так и в составе кластера. Поддерживает обе модели Pub-Sub и Point-to-Point, протоколы AMQP, MQTT, STOMP и другие. Реализованы гарантии доставки сообщений At most once и At least once.

В случае At most once получается большая пропускная способность, так как данные обрабатываются в быстрой оперативной памяти. At least once надёжный в плане доставки, но менее скоростной в плане передачи данных вариант, потому что используется механизм подтверждений и запись на диск.
{% endhint %}

## Принцип работы

В упрощённом виде принципы работы RabbitMQ можно представить так: приложение-отправитель (Publisher) публикует сообщения в брокер, ссылаясь на его внутреннюю сущность Exchange (Обменник). Обменник в зависимости от типа и настроек перенаправляет сообщения в одну или более связанных с ним очередей (Queue). Приложения-подписчики (Consumer) держат постоянное TCP соединение с RabbitMQ и ждут сообщения из заданной очереди. Брокер отправляет (push), распределяет сообщения между подписчиками. Если у очереди несколько подписчиков, сообщения между ними распределяются равномерно. Если сообщение успешно обработано подписчиком, оно удаляется из очереди.

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

Принцип «Умный брокер, тупой потребитель» по отношению к RabbitMQ означает, что брокер берёт на себя много дополнительных действий. Например, следит за прочитанными сообщениями и удаляет их из очереди. Или сам организует процесс распределения сообщений между подписчиками.

Источник:&#x20;

* <https://habr.com/ru/companies/innotech/articles/698838/>


# Kafka vs RabbitMQ

### Выбирая между Kafka и RabbitMQ

На самом деле, категорично сравнивать брокеры сообщений очень сложно. У всех существуют свои задачи и области применения. В случае с Apache Kafka и RabbitMQ это немного разный уровень, где лучшего не существует.

Kafka используется для обработки больших объёмов данных, сотен тысяч сообщений в секунду, которые подолгу хранятся на диске и много раз читаются сотнями или даже тысячами подписчиков. Kafka — это легко масштабируемая система, обладающая повышенной отказоустойчивостью, что очень важно в крупных проектах.

RabbitMQ более простой в установке и настройке, успешно справляется с асинхронным обменом данными в микросервисной архитектуре. Не требует дополнительных компонентов и затрат на дисковые ресурсы, так как все сообщения после чтения из очереди удаляются. По сравнению с Kafka обладает большими возможностями по настройке шаблонов обмена сообщениями. Отличный выбор, если нет завышенных требований к отказоустойчивости и пропускной способности.

<table data-full-width="true"><thead><tr><th width="229.33333333333331"></th><th>Kafka</th><th>RebbitMQ</th></tr></thead><tbody><tr><td>Простота установки</td><td>-</td><td>+</td></tr><tr><td>Объем данных </td><td>Большой, сотни тысяч сообщений в секунду</td><td>Небольшой</td></tr><tr><td>Обмен информацией</td><td>Pub-Sub</td><td>Pub-Sub и Point-to-Point</td></tr><tr><td>Гарантия доставки</td><td>At most once / At least once / Exactly once</td><td>At most once / At least once</td></tr><tr><td>Повышенная отказоустойчивость</td><td>+</td><td>-</td></tr><tr><td>Процесс распределения сообщений на стороне брокера</td><td>-</td><td>+</td></tr></tbody></table>

Источник: <https://habr.com/ru/companies/innotech/articles/698838/>


# ESB

{% hint style="info" %}
**Корпоративная сервисная шина (ESB)** представляет собой промежуточное программное обеспечение, обеспечивающее интеграцию различных приложений и систем в единую информационную среду. ESB служит для передачи данных между компонентами, выполнения преобразования данных в соответствии с требуемыми форматами и обеспечения унификации коммуникаций.
{% endhint %}

## Принцип работы

Сервисная шина управляет потоком информации, автоматически настраивает передачу данных, задает маршруты, осуществляет прием данных из одного приложения и отправку в другое. Информация из разных хранилищ представляется в корпоративном сервисе в различных форматах (протоколах), например, в DBF, JSON, CSV, XML и т.д. Взаимодействие приложений при обычной схеме обмена данными серьезно затруднено. Шина ESB автоматически преобразует информацию в подходящий формат(ы)(протокол(ы)) и отправляет в соответствующую систему (или разные системы).

<figure><img src="/files/BFH7e8jidWHCKW1lKf1d" alt="" width="563"><figcaption><p>Обычная схема данными</p></figcaption></figure>

<figure><img src="/files/eBy56Y1er6oPsyRkKHtk" alt="" width="563"><figcaption><p>ESB схема обмена данными</p></figcaption></figure>

## Основные компоненты

* **Брокер сервисов:** Управляет доступом к сервисам, регистрируя их и обеспечивая безопасность взаимодействия.
* **Адаптеры:** Предоставляют соединение с различными приложениями или системами, адаптируя их интерфейсы для работы в рамках ESB.
* **Мониторинг и управление:** Компоненты, предоставляющие инструменты для наблюдения за работой ESB, отслеживания производительности, обработки ошибок и административного управления.

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

## Преимущества

* **Упрощение интеграционных процессов:** Вместо многочисленных прямых интеграций между системами ESB предлагает стандартизированный подход, сокращая время и ресурсы, необходимые для внедрения новых связей.
* **Гибкость:** ESB позволяет легко добавлять, модифицировать или удалять системы без необходимости изменения основного кода, что делает архитектуру более адаптивной к изменениям.
* **Масштабируемость:** С ростом компании и появлением новых систем ESB способна масштабироваться, обеспечивая надежное и стабильное взаимодействие между большим количеством компонентов.
* **Улучшение качества данных:** С помощью ESB можно обеспечить контроль и преобразование данных, устраняя несоответствия и ошибки при передаче информации.
* **Снижение рисков:** Централизованный подход к интеграции через ESB уменьшает вероятность ошибок и сбоев, связанных с прямыми связями между системами
* **Экономия ресурсов:** ESB уменьшает необходимость в постоянной разработке и поддержке индивидуальных интеграций, что может существенно снизить IT-затраты организации.

## Недостатки

* **Сложность интеграции:** Несмотря на то что ESB призвана облегчить интеграцию систем, начальные этапы внедрения могут потребовать значительных затрат времени и ресурсов, особенно в сложных и фрагментированных IT-средах.
* **Зависимость от одного решения:** Если все интеграционные процессы привязаны к одной ESB-платформе, возможные сбои или проблемы в её работе могут парализовать деятельность всей компании.
* **Производительность:** В ситуациях с большим объемом данных и множеством транзакций ESB может стать узким местом, замедляя обработку данных.
* **Сложности масштабирования:** При росте бизнеса и увеличении числа интегрированных систем может потребоваться дополнительное масштабирование ESB, что влечет за собой дополнительные затраты.
* **Безопасность:** Так как ESB становится центральным звеном между множеством систем, она может стать целью для кибератак. Необходимо внимательно следить за обновлениями безопасности и регулярно проводить аудиты.
* **Стоимость и ресурсы:** Поддержка и обслуживание ESB может потребовать значительных инвестиций, как финансовых, так и в плане человеческих ресурсов.

Источники:&#x20;

* <https://vc.ru/u/957470-dynamicsun/514376-chto-takoe-integracionnaya-shina-esb>
* <https://habr.com/ru/companies/mygames/articles/671496/>
* <https://www.decosystems.ru/esb-integratsiya/>


# gRPC

быстрее REST за счёт бинарной сериализации HTTP/2

## RPC

{% hint style="info" %}
**RPC (**&#x72;emote procedure cal&#x6C;**)** — это форма взаимодействия клиент-сервер, в которой используется удаленный вызов функции, а не обычный вызов HTTP. Идея в том, что мы можем вызвать и выполнить функцию где-то на удаленной системе, как если бы это была локальная функция.
{% endhint %}

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

RPC использует IDL (Interface Definition Language - язык описания интерфейса) как форму контракта на вызываемые функции и тип данных.

## gRPC

{% hint style="info" %}
**gRPC (Google Remote Procedure Calling)** — система удаленного вызова процедур, разработанная компанией Google.
{% endhint %}

<details>

<summary><span data-gb-custom-inline data-tag="emoji" data-code="1f4ce">📎</span> Расшифровка "g"  в gRPC</summary>

Google как расшифровка литеры G — лишь одно из возможных значений. В зависимости от версии GRPC разработчики перебирают разные варианты расшифровок. Например, good для версии 1.1, generous для 1.8, game для 1.25 (с примером перечня можно ознакомиться на [ресурсе](https://grpc.github.io/grpc/core/md_doc_g_stands_for.html)). Перебор вариантов не несет особой смысловой нагрузки и является одной из пасхалок, которые так любит компания.

</details>

## Архитектура gRPC

<figure><img src="/files/KEY5YHzX2PDdcYOcDZSq" alt=""><figcaption><p>Запрос-ответ gRPC</p></figcaption></figure>

### HTTP/2

HTTP/1.1 долгое время оставался актуальным, затем в 2015 году, появился HTTP/2, который дополнил HTTP/1.1. Так,  HTTP/2 стал самым популярным транспортный протоколом в Интернете.

HTTP/2 — одна из важных причин, почему gRPC может работать так хорошо.

Расширение работы HTTP/2 включает:

* способы двоичного кадрирования информации (HTTP 1.1 работает с текстовыми данными)
* обеспечение полного [мультиплексирования ](#user-content-fn-1)[^1]для распараллеливания запросов
* возможность работы в полнодуплексном режиме с одновременной отправкой запросов клиента и получением ответов от сервера
* механизмы потоковой передачи наборов данных как со стороны клиента, так и от сервера
* приоритизацию сообщений
* сжатие заголовков передаваемых пакетов данных, уменьшающее траффик в сети

Все это возможно благодаря бинарной природе протокола HTTP/2 и позволяет микросервисам эффективно обмениваться информацией как в различных симплексных (однонаправленных) режимах, так и используя полноценное дуплексное (двунаправленное) соединение с одновременными приемом и передачей сообщений.

Посмотреть разницу в производительности между HTTP2 и HTTP1.1 можно по [ссылке](https://imagekit.io/demo/http2-vs-http1).&#x20;

### Protocol Buffer (Protobuf)

{% hint style="info" %}
**Protobuf** — буферный протокол сериализации (бинарного преобразования) структурированных данных (аналог JSON или XML). Это наиболее часто используемый IDL для gRPC. Здесь вы храните свои данные и функциональные контракты в виде так называемого прото-файла.
{% endhint %}

<details>

<summary>JSON vs Protobuf</summary>

gRPC по умолчанию использует ProtoBuf из-за его высокой производительности и эффективности. Однако, gRPC также поддерживает JSON и другие форматы, что делает его гибким для различных сценариев использования.

Подробнее про сравнение протоколов сериализации: [Protobuf vs JSON](/hard-skills/integracii/vidy-integracii/asinkhronnoe-vzaimodeistvie/grpc/protobuf-vs-json)

</details>

Преобразование данных в двоичный формат не зависит от программной платформы, что позволяет объединять микросервисы, реализованные на разных языках программирования. В отличие от структурированных данных текстовых форматов, таких как XML или JSON, бинарный формат позволяет эффективно сжимать пакеты сообщений при наличии ограничений на размер пакета (например, в каналах связи с невысокой пропускной способностью).

### Режимы взаимодействия API gRPC

GRPC предусматривает четыре возможных режима взаимодействия сервера и клиента:

* **Однонаправленный (Unary gRPC)**, когда после каждого запроса клиент ждет ответа от сервера.
* **Потоковая передача сервера (Server streaming gRPC)**, когда в ответ на запрос клиента сервер предоставляет поток сообщений. Для завершения передачи сервер посылает сообщение о состоянии.
* **Потоковая передача клиента (Client streaming GRPC)**, когда сервер принимает поток сообщений от клиента и отвечает одним подтверждающим сообщением.
* **Двунаправленный обмен (Bidirectional streaming GRPC)** с разделением каналов передачи сервера и клиента. В этом случае потоки сообщений одновременно передаются в обоих направлениях.

### Преимущества

* **Высокопроизводительные удаленные вызовы процедур**

Используя Protobuf и HTTP/2, сервисы gRPC обеспечивают в 10 раз более высокую производительность и защиту API по сравнению с взаимодействием REST+JSON. Благодаря использованию подталкивания сервера, мультиплексирования и сжатия заголовков, HTTP/2 обеспечивает высокопроизводительное ранжирование сервисов gRPC. Мультиплексирование позволяет устранить задержку в головной части линии, а server push дает возможность HTTP/2 передавать материал с сервера на клиент до того, как он потребуется. При использовании HTTP/2 сообщения сжимаются более эффективно, что приводит к более быстрой загрузке сервисов gRPC.

* **Потоковая передача**

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

* **Генерация кода**

Генерация кода для gRPC клиентских и gRPC серверных программ является ключевым компонентом gRPC веб-подхода. Для генерации кода из файла .proto модули gRPC используют компилятор .protoc. Формат Protobuf контролируется через генерацию кода в gRPC, который используется для определения форматов данных и конечных точек приложения. Он может создавать сетевые заглушки на стороне клиента и скелеты на стороне сервера, что сокращает время на разработку программ с различными сервисами в gRPC services.

* **Интероперабельность**

Многочисленные системы и языки программирования, такие как Java, Ruby, Go, C# и другие, поддерживаются ресурсами и библиотеками gRPC. Используя эти языки программирования, разработчики могут создавать производительные приложения, используя полную кросс-платформенную совместимость с gRPC. Это достигается благодаря бинарной форме подключения Protobuf и эффективной генерации кода практически для всех систем.

* **Безопасность**

Безопасность API обеспечивается в gRPC с помощью HTTP/2 через сквозную зашифрованную сессию TLS. gRPC способствует внедрению SSL/TLS для шифрования данных и аутентификации между сервером и клиентом gRPC.

* **Производительность и удобство использования**

Поскольку gRPC является полной альтернативой RPC, он работает без проблем на широком спектре систем и языков. gRPC также обладает отличным инструментарием, при этом многие необходимые шаблоны кода генерируются вручную. Инженеры теперь могут больше сосредоточиться на основной функциональности благодаря значительной экономии времени при использовании gRPC.

### Недостатки

* **Недостаточная зрелость**

Развитие технологии может быть существенным барьером для ее принятия. Это также очевидно при использовании gRPC. GraphQL Один из аналогов gRPC имеет более 14k запросов на StackOverflow, в то время как на gRPC на данный момент только чуть меньше 4k. Сообществу gRPC не хватает знаний о лучших практиках, решениях и успехах, потому что за пределами Google не так много программистов для HTTP/2, а также буферов протокола. Однако, по мере расширения сообщества gRPC и привлечения новых разработчиков, эта ситуация со временем изменится.

* **Ограниченная поддержка браузеров**

Поскольку ни один из существующих браузеров gRPC не может обрабатывать фреймы HTTP/2, вы не можете эффективно вызывать сервис gRPC из браузера, так как gRPC Web в основном зависит от HTTP/2. В результате вы должны использовать прокси-сервер с gRPC, что имеет ряд недостатков.

* **Нечитаемость человеком**

В отличие от XML и JSON, файлы Protobuf не читаются человеком, поскольку данные сжимаются до двоичного формата. Разработчики должны использовать дополнительные инструменты, такие как протокол отражения сервера и командная строка gRPC для оценки полезной нагрузки, устранения неполадок и создания ручных запросов.

* **Крутая кривая обучения**

В отличие от REST и GraphQL, которые в основном используют JSON, потребуется некоторое время, чтобы познакомиться с буферами протокола и открыть для себя методы борьбы с трениями HTTP/2.

## Примеры использования

1. **Коммуникация микросервисов:** gRPC широко используется в архитектурах микросервисов для обеспечения бесперебойной связи между различными сервисами. Его эффективный формат двоичной сериализации (буферы протокола) и поддержка потоковой передачи делают его идеальным для обработки больших объемов данных и связи в реальном времени.
2. **Приложения реального времени.** Благодаря поддержке двунаправленной потоковой передачи и отправки данных на сервер gRPC хорошо подходит для создания приложений реального времени, таких как чат-приложения, аналитика в реальном времени и системы отслеживания в реальном времени.

Источники:&#x20;

* <https://proglib.io/p/grpc-i-vse-vse-vse-chast-i-vvedenie-2021-03-26>
* <https://cloud.yandex.ru/docs/glossary/grpc>
* <https://wiki.merionet.ru/articles/chto-takoe-grpc-i-protobuf>
* <https://appmaster.io/ru/blog/chto-takoe-gpk#zakliuchenie>
* <https://habr.com/ru/companies/tinkoff/articles/780024/>
* <https://apidog.com/articles/what-is-grpc/>

[^1]: потоковая передача, которая позволяет выполнять несколько процессов (запрос/ответ) в рамках одного соединения


# Правила proto-контракта

{% hint style="info" %}
**Контракт** — это набор методов, объединенных в сервисы. Описание метода состоит из названия, сообщения запроса и сообщения ответа. В запросе и ответе можно как указать стандартные типы данных, так и составить свой объект с необходимым наполнением. Во втором случае потребуется придумать ему название и описать с ключевым словом message.
{% endhint %}

## **Правила, по которым строится запрос**

<figure><img src="/files/bGW8Gr9p0cU1TU3doEFR" alt="" width="563"><figcaption><p>Состав сервиса, метода и сообщения</p></figcaption></figure>

* Метод должен принимать что-то на вход и возвращать что-то на выходе — HelloRequest и HelloResponse. Если не нужно получать или отправлять какие-то данные, их можно заменить пустым значением google.protobuf.Empty. Тогда в ответ на запрос или в запросе не будут отправляться никакие данные, но придет код ответа. Ответ 2хх, если все успешно, или 4хх/5хх, если есть проблемы. Это позволяет снизить нагрузку на систему и повысить безопасность, передавая только самое необходимое.
* В методе должны быть указаны типы данных, которыми он оперирует. В примере выше это string для name и message, а также HelloRequest и HelloResponse для самого запроса. Если тип данных заранее неизвестен, можно использовать google.protobuf.Any, который заменяет любой тип данных.&#x20;
* У поля в сообщении должен быть неповторяющийся порядковый номер. Если какое-то поле было использовано ранее и удалено, этот номер повторно использовать нельзя. Такие поля можно резервировать ключевым словом reserved или оставляя комментарии.&#x20;

Для описания контракта используются ключевые слова:

* `‘syntax’` — текущая версия синтаксиса. Сейчас, как правило, новые сервисы пишутся на proto3.
* `‘import’` — для импорта стандартных пакетов. Например, “google/protobuf/timestamp.proto” загрузит тип данных timestamp.
* `‘service’` — для объявления сервиса. В сервис объединяют GRPC-методы
* `‘rpc’` — для объявления метода: его названия и request-сообщения.
* `‘returns’` — для объявления ответа метода, response-сообщения.
* `‘message’` — для объявления объекта.
* `‘enum’` — для объявления перечисления.
* `‘repeated’` — для объявления повторяющегося поля.
* `‘reserved’` — для резервирования поля.
* `‘optional’` или `‘required’`  — для объявления необязательного или обязательного поля. В proto3 этот функционал убран.
* `‘oneof’` — для объявления сложного поля, в котором можно получить одно из нескольких значений. Это довольно нагруженная и сложно обрабатываемая конструкция, которая может много весить и тратить кучу ресурсов, поэтому ее лучше не использовать, а заменить на что-нибудь другое. Например, на строку, в которой придет на самом деле json.&#x20;
* Целый набор стандартных типов данных вроде bool, string, int64 и других.

<details>

<summary>Пример proto-контракта</summary>

```protobuf
syntax = "proto3";
import "google/protobuf/any.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

 
service ProductService{
	// метод добавления книги в каталог
	rpc AddProduct(AddProductRequest) returns (google.protobuf.Empty) {}
    // метод получения книги по ID
	rpc GetProductById(GetProductByIdRequest) returns (GetProductByIdResponse) {}
    // метод получения всех книг
	rpc GetProductsList(GetProductsListRequest) returns (GetProductsListResponse) {}
}

message AddProductRequest{
	BookInfo add_book_info = 1;

}

message BookInfo{
	// эти поля нельзя будет использовать
	reserved 6, 15, 9 to 11;
	// данные об авторе не определены однозначно, и может прийти любой тип (строка или массив, например)
	google.protobuf.Any author = 1;
	string name = 2;
	int32 price = 3;
	Type type = 4;
	bool in_store = 5;
	// в типе bytes можно передавать файлы, но лучше заменить на ссылку в s3
	bytes book_cover = 7;
	// здесь мы будем использовать только одно из перечисленных полей,
	// для пользователя это выглядит как, например, динамичная форма ввода
	oneof additional_fields{
        // используем с TYPE_UNDEFINED — он пригодится, 
        // когда будут добавляться новые значения в enum Type: созданные объекты BookInfo примут этот тип по умолчанию
    	AdditionalFieldsUndefined additional_fields_undefined = 8;
    	AdditionalFieldsDetective additional_fields_detective = 12;
    	}
}

enum Type{
	TYPE_UNDEFINED = 0;
	TYPE_DETECTIVE = 1;
}

message AdditionalFieldsUndefined{
	string description = 1;
}

message AdditionalFieldsDetective{
	string description = 1;
	string period = 2;
}

message GetProductByIdRequest{
	// protobuf еще не знает, что такое uuid, поэтому его можно передать типами string, bytes или кастомным типом
	string id = 1;
}

message GetProductByIdResponse{
	string id = 1;
	BookInfo get_book_info = 2;
	google.protobuf.Timestamp created_at = 3;
}

// limit и offset нужны для пагинации на бэке. Если у нас бесконечная лента, можно вместо объекта GetProductsListRequest передать google.protobuf.Empty
message GetProductsListRequest{
	int32 limit = 1;
	int32 offset = 2;
}

message GetProductsListResponse{
	repeated BookInfo get_book_list_info = 1;
}
```

</details>

Источник: <https://habr.com/ru/companies/tinkoff/articles/780024/>


# Protobuf vs JSON

| Критерий                | Protocol Buffers (ProtoBuf)                                           | JSON                                                |
| ----------------------- | --------------------------------------------------------------------- | --------------------------------------------------- |
| **Формат данных**       | Бинарный                                                              | Текстовый                                           |
| **Размер сообщений**    | Обычно меньше, более компактные                                       | Обычно больше из-за текстового формата              |
| **Скорость обработки**  | Быстрее из-за меньшего размера и бинарной природы                     | Медленнее, требует парсинга текста                  |
| **Читаемость**          | Требует специальных инструментов для чтения и отладки                 | Легко читаем и отлаживаем человеком                 |
| **Интероперабельность** | Хорошая поддержка между различными япами                              | Отличная поддержка на всех платформах               |
| **Совместимость**       | Строгая совместимость, требует точного соответствия схемы данных      | Гибкая, легко адаптируется к изменениям             |
| **Типизация данных**    | Строго типизированный, требует определения всех полей                 | Динамически типизированный                          |
| **Использование**       | Предпочтительнее для высокопроизводительных и оптимизированных систем | Широко используется для веб-API и легкой интеграции |

Источник: <https://habr.com/ru/companies/otus/articles/780720/>


# Сравнительная таблица

<table data-full-width="true"><thead><tr><th width="172"></th><th width="244">SOAP</th><th width="266">REST</th><th>gRPC</th></tr></thead><tbody><tr><td><strong>Протокол</strong></td><td>HTTP1.1.</td><td>HTTP1.1.</td><td>HTTP2 (работает в двух направлениях и за счет этого быстрее HTTP1.1)</td></tr><tr><td><strong>Подход</strong></td><td>сервисно-ориентированный дизайн. Клиент запрашивает у сервера услугу или функцию, которая может затрагивать ресурсы сервера</td><td>объектно-ориентированный дизайн. Клиент запрашивает у сервера создание, совместное использование или модификацию ресурсов</td><td>сервисно-ориентированный дизайн. Клиент запрашивает у сервера услугу или функцию, которая может затрагивать ресурсы сервера</td></tr><tr><td>                              </td><td>                                                    </td><td>                                                          </td><td>                                                                               </td></tr><tr><td><strong>Формат передаваемых данных</strong></td><td><p>Запрос: XML</p><p>Ответ: XML</p></td><td><p>Запрос: преимущественно JSON (реже XML)</p><p>Ответ: JSON со всеми данными, найденными на сервере по этой конечной точке</p></td><td><p>Запрос: бинарный файл — protobuf.</p><p>Ответ: бинарный файл — protobuf.</p></td></tr><tr><td><strong>Контракт</strong></td><td>обязательны WSDL-схемы</td><td>необязательно OpenAPI (Swagger), эндпоинты могут быть не задокументированы</td><td>обязательно пишется по стандарту Protocol Buffers, компилируется внутренним компилятором protoc, который генерирует необходимый исходный код классов из определений в proto-файле</td></tr><tr><td><strong>Документирование</strong></td><td>WSDL-схемы сложно писать и поддерживать</td><td>в JSON нужно задокументировать содержащиеся в нем поля и их типы. Часто информация может быть неточной, неполной или устаревшей.</td><td>четко определенная и самодокументируемая схема. API на Protobuf генерирует код, код не будет рассинхронизирован с документацией. При генерации кода из Protobuf проходит базовая проверка — сгенерированный код не принимает поля неправильного типа.</td></tr><tr><td><strong>Вес</strong></td><td>XML весит больше аналогичных JSON и base64 и в основном применяется в legacy-системах, которые были разработаны в конце 1990-х — начале 2000-х.</td><td>JSON меньше XML, но больше protobuf</td><td>меньше JSON</td></tr><tr><td><strong>Производительность</strong></td><td>Средняя, данные требуют дополнительной сериализации (парсинга)</td><td>Средняя, данные требуют дополнительной сериализации (парсинга)</td><td>Высокая, данные изначально сериализованы</td></tr><tr><td>                              </td><td>                                                    </td><td>                                                          </td><td>                                                                               </td></tr><tr><td><strong>Связь с сервером</strong></td><td></td><td>1—1</td><td>1—1, 1—N, N—N</td></tr><tr><td><strong>Скорость обмена</strong></td><td></td><td>Средняя, обмен однонаправленный (запрос-ответ)</td><td>Высокая, обмен двунаправленный или стриминговый</td></tr><tr><td><strong>Как передает данные</strong></td><td>использует только HTTP-POST-запросы</td><td><p>создает <strong>разовое</strong> соединение между двумя точками: создал соединение, отправил и закрыл. Клиент шлет в API сообщения и сразу получает ответ или ждет формирования ответа. Клиенту и серверу не нужно знать о внутренних данных. </p><p>Использует четыре основных метода HTTP: GET, POST, PUT, DELETE.</p></td><td><p>создает <strong>постоянное</strong> соединение — сокет — между двумя точками, по которому передает бинарный файл и вызывает удаленно функцию, передавая в нее параметры. Шлет сообщения в обе стороны: gRPC обеспечивает двунаправленную потоковую передачу данных — и клиент, и сервер могут одновременно посылать и получать несколько запросов и ответов в рамках одного соединения. REST так не умеет. </p><p>Использует только HTTP-POST-запросы.</p></td></tr><tr><td><strong>Число конечных точек (точек входа в приложение)</strong></td><td>1</td><td>без ограничений</td><td>1</td></tr><tr><td>                              </td><td>                                                    </td><td>                                                          </td><td>                                                                               </td></tr><tr><td><strong>Работа в вебе</strong></td><td>без допусилий</td><td>без допусилий</td><td><p></p><p>с дополнительными усилиями: </p><ul><li>gRPC работает на HTTP2 и передает бинарный файл, а JS в браузере работает на HTTP1 и взаимодействует только с текстовыми файлами. Поэтому существует gRPC-WEB, который может положить base64 в тело текстового сообщения, а затем JS отдельной библиотекой переводит base64 в JSON. gRPC-WEB —  отдельный от gRPC протокол, существует только в браузере и действует как уровень перевода между gRPC и приложением в браузере.</li><li>Фронтовый кодген не знает, где поле обязательное, а где нет. Все не базовые типы генерируются как optional.</li><li>Стримы для фронта стали доступны не так давно. Раньше для отправки файла писали rest-точку.</li></ul></td></tr><tr><td><strong>Для какой архитектуры</strong></td><td>сложная архитектура, выходящая за рамки CRUD. SOAP используют многие банки.</td><td>преимущественно CRUD. Самая популярная архитектура API для веб-сервисов и микросервисных архитектур.</td><td>преимущественно CRUD</td></tr><tr><td><strong>Мультиязыковая поддержка</strong></td><td>Не зависит от языка</td><td>Средняя, требуются сторонние сервисы для мультиязыковых систем</td><td>Высокая, встроенная автоматическая генерация кода для популярных языковых сред</td></tr><tr><td><strong>Достоинства</strong></td><td><ul><li>Не зависит от языка.</li><li>Встроенная обработка ошибок.</li><li>Встроенный протокол безопасности.</li><li>Самодокументируемый.</li></ul></td><td><p></p><ul><li>Клиент отделен от сервера.</li><li>Нет длительного соединения с отслеживанием состояния → экономия ресурсов.</li><li>Масштабируемость.</li><li>Простой в использовании и понимании, большое комьюнити.</li><li>Есть стандартный список кодов ошибок, но все пользуются им по-своему.</li><li>Можно внедрять в самых разных форматах без стандартного программного обеспечения.</li><li>Кэширование на уровне HTTP без дополнительных модулей.</li></ul></td><td><p></p><ul><li>Высокая производительность и низкая нагрузка на сеть.</li><li>Держит соединение, не надо тратить время на подключение.</li><li>Можно поставить таймаут клиента и тем самым экономить ресурсы.</li><li>Строгая спецификация типов данных. Под каждое поле выделяет набор битов по порядку.</li><li>Стандартизация кодов ошибок, зашитая в protobuf.</li><li>Сам генерирует исходный код по proto.</li><li>Самодокументируемый.</li><li>Не зависит от языка, контракт везде одинаковый.</li><li>Можно использовать для управления контейнерами в k8s и системами хранения данных.</li></ul></td></tr><tr><td><strong>Недостатки</strong></td><td><p></p><ul><li>Тяжелый XML.</li><li>Сложный набор правил для описания контракта.</li><li>Долгое обновление сообщений — особенности схемы.</li><li>Постоянная необходимость в кодировании данных на сервере до передачи по каналам связи и их последующем декодировании на клиенте.</li></ul></td><td><p></p><ul><li>Избыточная нагрузка на сеть.</li><li>Избыточная или недостаточная выборка данных.</li><li>Нет документирования и стандартизации.</li><li>Нет стандарта использования кодов ответов, поэтому часто в успешных кодах могут передаваться ошибки.</li><li>Постоянная необходимость в кодировании данных на сервере перед передачей по каналам связи и последующем их декодировании на клиенте.</li></ul></td><td><p></p><ul><li>Не работает без gRPC-WEB в браузере.</li><li>Человек не прочитает сообщение без декодера.</li><li>Для работы нужно программное обеспечение gRPC как со стороны клиента, так и со стороны сервера.</li></ul></td></tr><tr><td><strong>Когда использовать</strong></td><td>финтех и другие долгие массивные проекты со сложной архитектурой, легаси с 90-00 хх гг. или исторически выбранный SOAP, от которого не отказаться. Для нового проекта, возможно, стоит присмотреться к альтернативам.</td><td>благодаря простой реализации и отображению структуры данных, удобству чтения с ним легко работать начинающим программистам.</td><td>разработан для того, чтобы дать разработчикам возможность создавать высокопроизводительные API для микросервисных архитектур в распределенных центрах обработки данных. В том числе для микросервисных архитектур на нескольких языках программирования, для которых API вряд ли будет меняться со временем. Также он хорошо подходит для внутренних систем, требующих потоковой передачи данных в реальном времени и загрузки больших объемов информации.</td></tr></tbody></table>

Источник: <https://habr.com/ru/companies/tinkoff/articles/780024/>


# Другое

## Файловый обмен

Данный метод интеграции появился достаточно давно и проверен временем. Смысл метода в том, что система номер 1 передает в систему номер 2 файл в установленном формате(например csv).&#x20;

***Плюсы данного подхода:***

* Простота&#x20;
* Отсутствие необходимости соединения между системами

***Недостатки:***

* Скорость
* Ненадежность
* Отсутствие возможности получить информацию о валидности файла со стороны вызывающей системы

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

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

## База к базе (или общая база данных)

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

На самом деле для реализации  данного подхода не обязательно, чтобы база была общей. Например в СУБД ***Oracle*** присутствует механизм ***database links***, который позволяет получать в одной базе данных данные из другой.

***Плюс данного подхода:***

* Простота

***Недостаток:***

* Подход создает сильную связанность между системами

***Такой метод обмена является асинхронным***, поскольку чаще всего подход ***database links*** работает в одном направлении и данные в системе-получателе появляются только по запросу, т.е создать, например триггер, который отправляет данные в другую базу данных при заданном событии не получится.

Источник:&#x20;

* <https://habr.com/ru/companies/itq_group/articles/705598/>


# WebSocket API


# Sync vs Async

<table data-full-width="true"><thead><tr><th width="476">Синхронное взаимодействие</th><th>Асинхронное взаимодействие</th></tr></thead><tbody><tr><td>Выполнение последовательных операций</td><td>Выполнение независимых операций</td></tr><tr><td><p>Request-Response (Запрос-Ответ)</p><p></p><p>One-Way (Односторонний) или Fire and Forget (Отправил и забыл)</p></td><td><p>Publish-Subscribe (Публикация-Подписка)</p><p></p><p>Point-to-Point (Точка-Точка)</p></td></tr><tr><td>Ожидание завершения операций перед продолжением</td><td>Немедленное продолжение выполнения без ожидания</td></tr><tr><td>Прямая передача данных</td><td>Передача данных через промежуточные каналы</td></tr><tr><td>Простота и понятность кода</td><td>Большая гибкость и возможность распределенной обработки данных</td></tr><tr><td>Используется для низконагруженных систем</td><td>Используется для высоконагруженных систем, с большим количеством потоков информации</td></tr></tbody></table>




---

[Next Page](/llms-full.txt/1)

