# Базы данных – Эссе
### Андреев Антон – БПИ206
#### Рассуждения + Примеры

SQL vs NoSQL
NoSQL БД
---
Начну именно с не реляционных баз данных, потому что в основном их используют для узких кейсов совместно с реляционками, а значит они редко бывают в центре внимания. Пусть хотя бы в эссе у Антона Андреева будут первыми
Сначала давайте вспомним самые известные типы NoSQL баз (черным в списке популярных субд выделено то, что я буду использовать в своем эссе):
- Ключ-значение (**Redis**)
- Документо-ориентированные (**MongoDB**, Couchbase)
- Графовые (Neo4j)
- Колоночные (ClickHouse - куда же без него, Cassandra)
Безусловно, я мог начать рассказывать заезжанные примеры про соц сети и графовые БД или про запросы от аналитиков в команде и использование Cassandr'ы, но решил, что самому мне будет полезно рассказать про реализацию моего будущего курсового проекта
Суть проекта:
Парсинг апи ООН, где каждая страна публикует информацию об импорте и экспорте (кроме России - ЦБ запретил Таможне)). Однако на основе данных других стран мы можем восстановить информацию о собственной экономике. Такой подход называется "зеркальная экономика". После парсинга в БД (какую расскажу дальше) мы, естественно, уже другим сервисом это обрабатываем, чего-то считаем, отдаем точечки для графиков на фронт (туда их) и т.д.
После парсинга я решил, что лучше всего складывать данные в MongoDB (сразу скажу, что в JSONB в Postgre я не увидел смысла, так как в монге будет одна коллекция, поэтому зачем мне вообще распыляться на реляционку с постгрей)
Так почему же здесь удобнее документо-ориентированная БД???
Потому что в зависимости от переданных в request param значений мы получаем разные ответы, однако с одной верхнеуровневой схемой (это ли не наилучший вариант для монги)
Верхнеуровневую схему коллекции контролим в виде DTO в коде, а кучу разных по набору параметров документов храним в документах этой коллекции.
Плюс, у нас постоянно растущий объем данных: новая информация от всех стран постится раз в месяц, а в монге нам куда удобнее горизонтально масштабироваться с помощью шардинга.
Возможно, не совсем понятно, почему же данные, полученные от апи, могу отличаться.
Вот пример: иногда у конкретного товара кроме partnerCode, есть partnerCode2 (страна, в которую отправился товар впоследствии).
Плюс у каждого товара разные классификации, которые указываются разными параметрами, к примеру ресурсы и высокие технологии обозначаются разными способами.
На самом деле я могу долго перечислять, чем данные разнятся, но проще всего будет показать Вам один из элементов полученной даты (data), в котором многие поля просто в null'ах, так как они не использованы для конкретного набора request param.
P.S. я половину параметров не могу описать, поэтому картинку вставил, а не словами написал))

Еще я обещал сказать про Redis:
Так как это ключ-значение БД, то выглядит идеальным хранить точки для графиков фронта именно там. Условно мы хотим получить информацию по количеству товаров от конкретной страны. Тогда в Redis мы можем обратиться по ключу=код страны, и получить набор значений=кол-во товаров в конкретный месяц, а на его основе отрисовать график. Звучит круто, логично, удобно!
P.S. для более удобного фильтра в ключе можем хранить больше, чем код страны, благо в редисе есть разные типы данных
Реляционная БД
---
Сервис - FGED (Funny Gifs for Every Day)
Пока вставлял гифку решил, что за смешными движущимися картинками будущее или прошлое, уже не понятно во всей этой постиронии.
Итак, описание:
1. User (id (serial PK), nickname, description, password). Если рассуждать в формате ORM, то еще у User'a есть список с загруженными гифками.
2. Gif (id(PK), url файла на сервере (не хранить же всю гифку в бдшке), количетсво хохотушек (обычные лайки), user_id (кто загрузил гифку), number_of_wins (количество побед в баттле))
3. Battle (fisrtGif_id (FK), secondGid_id (FK), winner_id, battle_time, PK (fisrtGif_id, secondGid_id)) - гифка победитель определяется количеством хохотушек после того, как вышло время, указанное в battle_time. После баттла кол-во хохотушек обнуляется.
Воркфлоу:
Пользователь регистрируется, указывает уникальный никнейм, пишет описание себя (типо люблю аниме и котят)
Пользователь грузит гифку - она сохраняется на сервере и в бд добавляется путь к ней, number_of_wins = 0, hohotushki = 0, user_id = id загрузившего
Пользователь может посмотреть страницу другого юзера и выставить одну из своих гифок на баттл с гифкой второго пользователя.
Почему здесь реляционка?
У нас заранее известна структура всех сущностей, плюс между сущностями есть связи.
Банально, чтобы выбрать самоых крутых пользователей (гигачада), нам нужно обойти таблицу с гифками по уменьшению number_of_wins, взять user_id, сджойнится по нему и забрать nickname
Плюс реляционка поддерживает ACID, т.е. мы можем быть уверены в правильной фиксации количества хохотушек в режиме реального времени
Знаю, что для реляционки я мало описал, но как я говорил в самом начале (NoSQL db редко в центре внимания, поэтому по реляционкам и текста меньше))