Как стать автором
Обновить
241.24
AGIMA
Крупнейший интегратор digital-решений

SQL vs NoSQL: как выбрать архитектуру БД для мобильного приложения, чтобы потом не пришлось ничего переписывать

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров6.8K

Привет! Меня зовут Никита Грибков, я Flutter-разработчик в AGIMA. В сети море статей о различиях между SQL и NoSQL, но в большинстве из них много теории и почти совсем нет прикладных советов. Я пошел другим путем: ниже постараюсь внятно объяснить, какую систему и в каком случае выбирать. Спойлер: всё зависит от проекта и амбиций заказчика. Конечно, сосредоточусь на мобильной разработке, но основные принципы подойдут и в вебе.

Базовая теория

Вы точно видели на Хабре десятки статей, в которых описывают разницу между SQL и NoSQL. И хотя я поставил перед собой цель не повторяться, всё-таки описать основные моменты я должен. Постараюсь сделать это покороче и затем приложу пару ссылок на хорошие и более подробные статьи.

Если вы здесь не за этим, то ниже найдете классные графики эффективности SQL и NoSQL на разных мобильных платформах, а в конце — четкие советы, как между ними выбирать. А блок с теорией можно пропустить.

SQL (Structured Query Language) — это язык запросов, которые мы используем для работы с реляционными базами данных. У таких БД жесткая структура в виде таблиц. Вся информация там хранится в столбцах и строках. Так что структурированность — одно из главных преимуществ SQL баз данных.

Еще SQL — это надежно, поскольку у него большое сообщество и длинная история. Какие бы проблемы ни возникали с SQL в прошлом, сейчас они решены. А если даже что-то и пойдет не так — точно есть у кого спросить. Поэтому разработчику остается только писать кастомные ивенты: селекторы, джойны и т. д.

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

Подробно об обоих подходах можно почитать у коллег.

Преимущества и недостатки SQL

Плюсы

Минусы

SQL подходит для более сложных задач. Если у тебя 10 тысяч чеков и тебе нужно посмотреть, сколько ты потратил за год на молоко, то важно иметь под рукой структурированную таблицу. В ней будет отдельное поле «Молоко», и SQL сможет собрать данные именно по ней. А чтобы работать с NoSQL в таком формате, придется выгрузить базу данных целиком, пробежаться по всему массиву наших чеков, выделить поле «Молоко» и только потом с ним работать. Это неудобно, поэтому тут явно лучше SQL.

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

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

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

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

Сложная масштабируемость. Допустим, у нас две таблички — два каких-то класса, которые мы собираемся хранить. Чтобы хранить третий класс, придется начинать всё сначала: создать под него табличку и написать под него ивенты, которые будут срабатывать. В SQL нет какого-то общего пространства, в котором мы создаем объект и потом с ним работаем.

Преимущества и недостатки NoSQL

Плюсы

Минусы

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

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

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

Ограниченная поддержка транзакций. Нужно приложить много усилий, чтобы сделать базу данных NoSQL такой же безопасный, как SQL. Об этом я уже упоминал выше. Например, во Flutter можно использовать отдельный изолят, то есть отдельный поток, для выполнения этих транзакций. На основном потоке, на котором запущено всё приложение, обрабатывается логика, рисуются UI-интерфейсы, рендерятся объекты и прочее. А на параллельном запросе происходят транзакции. Так мы гарантируем, что транзакция будет быстрая и надежная.

Использование во Flutter, Kotlin и Swift

Для разных платформ подходят разные виды баз данных SQL:

  • Flutter: поддерживает SQLite — это библиотека, которая работает на базе SQL, но при этом доработана под мобильное приложение.

  • Kotlin: чаще всего используют Room — это что-то вроде интерфейса для работы с SQL базами данных.

  • Swift: обычно применяют CoreData — фреймворк для управления SQL.

Для NoSQL на всех трех платформах чаще всего можно увидеть использование общих решений. Это может быть облачная платформа Firebase или MongoDB. MongoDB в Kotlin и Swift представлена в виде библиотеки Realm, на Flutter либа с одноименный названием.

Но отдельно расскажу про Isar — крутую NoSQL базу данных для Flutter. Ее сделали ребята, которые раньше работали над библиотекой Hive. По сути, Isar — это улучшенная версия Hive, и она действительно сильно выигрывает у других нереляционных баз.

  1. Isar очень быстрая. Это отчасти снимает проблему с транзакционной безопасностью. Пользователь просто не успевает сделать что-то, что прервет транзакцию. 

  2. У Isar есть статическая типизация.

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

  4. В Isar много функций, и среди них — полнотекстовый поиск.

    Предположим, у вас есть класс юзера, у которого есть ID, имя, фамилия, год рождения. Таких юзеров в базе 10 тысяч. Чтобы работать с типичной базой NoSQL, нам нужно сделать запрос на выгрузку всех пользователей, пробежаться по всему массиву, и отфильтровать нужных людей. В Isar же не нужно проводить столько операций. Можно просто отфильтровать по определенному полю, примерно как в SQL. Поэтому мы можем одним запросом отсортировать базу данных, запросить только нужных пользователей и вернуть их.

  5. В Isar встроен полезный инструмент — линки. Они позволяют настроить отношение одного объекта к другому.

Перформанс приложения

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

В этом случае нас интересуют четыре действия:

  • создание запроса;

  • чтение объектов;

  • обновление;

  • удаление.

Вот что у нас получается:

Чем меньше миллисекунд уходит на обработку запроса, тем лучше. На графике видно, что Room создает запросы быстрее, чем Realm. Но разница настолько незначительная, что пользователь вообще вряд ли что-то заметит. Видим, что на Flutter намного быстрее Isar, а на Swift — реляционный CoreDate. Измерения проводились на одинаковых объемах и типах данных, график может немного измениться при других вводных.

Однако эти цифры помогают увидеть разницу между SQL и NoSQL. NoSQL зачастую быстрее и эффективнее.

Так как же выбрать между SQL и NoSQL?

Тут всё зависит от потребностей и задач бизнеса.

  • Если вы делаете маленькое приложение на узкую аудиторию или если вы делаете MVP для проверки гипотезы, то можно смело выбирать NoSQL-решение. Такие базы быстрые, с ними проще работать, они легко масштабируются. А если проект растет как на дрожжах — NoSQL можно быстро переписать на SQL.

  • Если вы делаете средний по объему проект, я бы рекомендовал SQL. Хотя, если очень хочется, то можно и NoSQL. Но тут есть некоторые особенности: выбирайте нереляционные базы, только если у вас есть налаженные ивенты, налаженная имплементация баз данных и опыт работы с NoSQL.

  • Если вы делаете энтерпрайз-решение, советую обращаться только к SQL. Представим, что в каком-то крупном маркетплейсе 10 тысяч пользователей оплатили покупки, но не получили товары, потому что транзакция данных прошла некорректно. Цена ошибки тут слишком высока — поэтому только SQL.

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

Что еще почитать

Теги:
Хабы:
+9
Комментарии16

Публикации

Информация

Сайт
www.agima.ru
Дата регистрации
Дата основания
Численность
501–1 000 человек
Местоположение
Россия
Представитель
Кристина Ляпцева