# Базы данных – Эссе ### Андреев Антон – БПИ206 #### Рассуждения + Примеры ![gif_180.gif](https://i.pinimg.com/originals/b3/95/47/b39547105331a2f32913defec3a5958b.gif) 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. я половину параметров не могу описать, поэтому картинку вставил, а не словами написал)) ![img.png](https://i.ibb.co/7GPQ9CC/data.jpg) Еще я обещал сказать про 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 редко в центре внимания, поэтому по реляционкам и текста меньше))