Привет! Меня зовут Никита Грибков, я 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 нет какого-то общего пространства, в котором мы создаем объект и потом с ним работаем. |
Преимущества и недостатки 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, и она действительно сильно выигрывает у других нереляционных баз.
Isar очень быстрая. Это отчасти снимает проблему с транзакционной безопасностью. Пользователь просто не успевает сделать что-то, что прервет транзакцию.
У Isar есть статическая типизация.
Isar, благодаря реактивности и внутренней архитектуре, хорошо масштабируется. Поэтому может сохранять асинхронные и синхронные запросы.
В Isar много функций, и среди них — полнотекстовый поиск.
Предположим, у вас есть класс юзера, у которого есть ID, имя, фамилия, год рождения. Таких юзеров в базе 10 тысяч. Чтобы работать с типичной базой NoSQL, нам нужно сделать запрос на выгрузку всех пользователей, пробежаться по всему массиву, и отфильтровать нужных людей. В Isar же не нужно проводить столько операций. Можно просто отфильтровать по определенному полю, примерно как в SQL. Поэтому мы можем одним запросом отсортировать базу данных, запросить только нужных пользователей и вернуть их.В 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 в частности — подписывайтесь на телегу нашего тимлида Саши Ворожищева.
Что еще почитать
Комментарии (14)
GameOwner
28.05.2024 15:46+2Для хайлоада с 1М+ запросов на модификацию NoSQL гораздо предпочтительнее.
Для 10М+ только NoSQL и остается.
Хотя очевидно, что подобные требования нужны 0.0001% проектам :)
Kahelman
28.05.2024 15:46+8Похоже чат-ГПТ голлюцинирует….
Если вы делаете маленькое приложение на узкую аудиторию или если вы делаете MVP для проверки гипотезы, то можно смело выбирать NoSQL-решение. Такие базы быстрые, с ними проще работать, они легко масштабируются. А если проект растет как на дрожжах — NoSQL можно быстро переписать на SQL
Удачи вам NoSQL в SQL переделывать….
Похоже автор вообще в руках баз данных не держал. Сравнивать абстрактный nosql с абстрактным sql на техническом ресурсе это уже за гранью добра и зла
если свести всю статью к одной фразе:
Не знаете как делать- берите SQLite.
Будет шанс смигрироватт на PostgreSQL без большой головной боли. Или раскидаете данные по разным SQLite базам - скорее всего вы не Google и не FB и SQLite покроет потребности всех ваших 10-100 клиентов
Neikist
28.05.2024 15:46Чет я довольно сильно сомневаюсь что постгрю можно в принципе на мобилке развернуть. И что это вообще кому нибудь нужно.
С другой стороны в этом плане проблема в статье. Почему то сравниваются именно для мобилок базы встраиваемые, а в конце вывод делается почему то для бека. Так что тоже склоняюсь к выводу что статью писали либо совсем невнимательно, либо нейронка.
Fell-x27
28.05.2024 15:46+1Выбор между SQL и noSQL это, как по мне, выбор между дрелью и молотком. Как вообще можно между ними выбирать? Да еще и с прицелом "сначала возьму одно, а потом, мб перепишу на другое". Это так не работает. Не хотел бы я в штате иметь архитектора, который выбирает между noSQL и SQL. Очевидно, что этот архитектор просто профнепригоден и не понимает, что делает.
Если нужно работать с цельными сущностями и тебе нужно просто "тупое хранилище", используй для этой цели noSQL, ведь просто SQL будет оверкиллом. Если нужно работать с декомпозированными данными - используй SQL, ведь...ды просто а что тебе еще использовать? :)
Это, блин, штуки, для разных задач. У них из общего - только 3 символа в названии подхода к работе. Но так-то и дрель с молотком это "строительные/монтажные инструменты" , да?
leon-mbs
28.05.2024 15:46+1Хайп вокруг nosql давно прошел когда стало очевидно что "серебряной пули" из них не получилось и nosql базы заняли отвдеенную им нишу быстрой обработки больших объемов key-value данных
sergey-gornostaev
28.05.2024 15:46Если вы делаете маленькое приложение на узкую аудиторию или если вы делаете MVP для проверки гипотезы, то можно смело выбирать NoSQL-решение. Такие базы быстрые, с ними проще работать, они легко масштабируются.
И часто у вас в маленьких приложениях на узкую аудиторию не хватает производительности СУРБД или возникает потребность в горизонтальном масштабировании?
Если вы делаете энтерпрайз-решение
То у вас, вероятно, будет множество разнотипных баз данных.
Hivemaster
28.05.2024 15:46Базы данных NoSQL быстрые и легкие.
Давно например MongoDB лёгкой-то стала?
Kanut
28.05.2024 15:46+2SQL vs NoSQL: как выбрать архитектуру БД для мобильного приложения, чтобы потом не пришлось ничего переписывать
И сразу вспомнилось:
Четырнадцатый том сочинений Боконона озаглавлен так: «Может ли разумный человек, учитывая опыт прошедших веков, питать хоть малейшую надежду на светлое будущее человечества?» Прочесть Четырнадцатый том недолго. Он состоит всего из одного слова и точки: «Нет.»
«Колыбель для кошки»
MANAB
28.05.2024 15:46Исходя из статьи, такое ощущение, что бд хранится у каждого пользователя приложения своя, сервер с API не нужен или вообще без БД. Почему у меня такое ощущение? Потому что ни слова про запросы API и сервер и потому, что автор писал, что если пользователь заероет приложение, то данные в noSQL не сохранятся или сохранятся битые.
То ли я не понимаю подхода, который использует автор, то ли автор не понимает, как пользоваться базами данных.
Cobalt
Как надо не любить читателей чтобы советовать им Isar ? Достаточно посмотреть что она уже больше года не обновляется, а обещанная 4 версия и того дольше "в разработке" находится. Вещь совершенно не юзабельная. Да хотяб просто вспомнить что Isar - это поменявший название и много вызвавший негатива в прошлом Hive! В нем остались все те же проблемы и добавилось еще куча новых. Чтобы потом не пришлось переезжать - используйте Sqlite или ОРМ для него Drift. Вообще не используйте NoSQL решения в проектах чуть сложнее калькулятора - потом будет больно переписывать!
GameOwner
Для ряда проектов SQL просто не позволит физически реализовать функционал-в силу чудовищной стоимости либо невозможности на текущем железе поднять инфру. Какой-нибудь средненький HFT фонд, катающий скромные 100М уе объема в сутки, желающий держать на своих серверах хотя бы сотню торгуемых инструментов-легко запишет весь требуемый датафид, используя EventSource/CQRS/NoSQL, с требуемой скоростью доступа к материализованному представлению по этим данным, правильно заточенному-будь то OrderBook либо подготовленные данные под ML, SQL на любой платформе и на любом железе для такого скромного набора датафидов скажет-"наши полномочия всё" :) А ведь есть те конторы, что хранят тысячи датафидов десятков бирж :) Кто-то правда еще дальше пошел и использует kdb+, но у него свои нюансы, начиная от стоимости, заканчивая пиковым перформансом, при прямых руках собственные реактивные велосипеды выходят шустрее.
Cobalt
Разговор именно про встраиваемую БД. На серверах можно использовать что угодно. Там у NoSQL решений нет таких проблем с безопасностью, производительностью и масштабируемостью как на мобилках.
Kahelman
1000 датафидов спокойно отображается в 1000 SQLite файлов. Так что SQL вам дозволит проводить обработку. В этом случае все-равно будет многопоточность приложение и большинство данных будут просто держаться в памяти. База нужна в редких случаях чтобы исторические данные подтянуть. А там где реальный HFT ( когда считают наносекунды потерянные на передачу данных по оптическому каналу) все равно будут использовать что-то своё и узко специализированное
Atreides07
Я вот с Isar переехал на sqlite с Drift и столкнулся с неожиданной багой. На проде и только на проде Drift периодически выбрасывает DriftRemoteException (Code 5) хотя подключение к БД открываю только один за время жизни приложения. Специально локально писал нагрузочные тесты с асинхронными запросами что бы воспроизвести проблему локально, но так и не получилось воспроизвести проблему. Я в итоге шаманствами с подключениям жизненного цикла пофиксил проблему, но осознанного и уверенного решения проблемы так и не получил. Поэтому и с Drift надо идти на прод осторожно.