Skip to content

SQL vs NoSQL

Sᴛѧʀʟɪɴɢ edited this page Feb 25, 2019 · 3 revisions

Где можно хранить данные?

Простой пример: регистрация пользователя.

Хранение данных в глобальной переменной

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

var users = []
app.post('/users', (req, res) => {
  const user = req.body;
  users.push(user);
  res.send('successfully registered')
});

Проблемы:

  • оперативная память дорогая
  • память очищается каждый раз, когда приложение перезапускается
  • возможно переполнение памяти, если её не чистить

Хранение данных в файле

Cохранние пользовательских данных в файловой системе помогает избежать
ранее перечисленных проблем.

const fs = require('fs')
app.post('/users', (req, res) => {
  const user = req.body
  fs.appendToFile('users.txt', JSON.stringify(user), err => res.send('successfully registered'));
});

Проблемы:

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

Поэтому данные хранят в базах данных.

СУБД

Системы управления базами данных (СУБД) — это высокоуровневое ПО, работающее
с низкоуровневыми API.

СУБД — это общий термин, относящийся ко всем видам абсолютно разных инструментов.
Эти инструменты управляют или помогают управлять наборами данных.

Модели баз данных

СУБД основаны на моделях баз данныхопределённых структурах для обработки данных.

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

Реляционная модель

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

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

Безмодельный (NoSQL) подход

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

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

Реляционные СУБД

РСУБД реализуют реляционную модель.
Они гарантируют надёжность, прозводительность и защиту информации от потерь.

РСУБД требуют чётких и ясных схем.
Эти рамки, определённые пользователем, задают способ их хранения и использования.
Схемы очень похожи на таблицы, столбцы которых отражают порядковый номер и тип
информации в каждой записи, а строки — содержимое этих записей.
Перед тем, как сохранить данные, нужно задать типы различных значений. (имя - строка, количество - число).

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

Примеры: SQLite, MySQL, PostgreSQL

NoSQL-СУБД

NoSQL-СУБД не используют реляционную модель структуризации данных.

Существует много реализаций NoSQL-СУБД.
Они не имеют схему и допускают неограниченное формирование записей и хранение данных в виде ключ-значение.

В отличие от традиционных РСУБД, некоторые базы данных NoSQL, например, MongoDB,
позволяют группировать коллекции данных с другими базами данных. Такие СУБД
хранят данные как одно целое. Эти данные могут представлять собой одиночный
объект наподобие JSON (что хорошо сочетается с JS) и вместе с тем корректно
отвечать на запросы к полям.

Никогда нельзя гарантировать, что данные консистентны и никогда нельзя узнать,
какая структура находится в базе данных.

NoSQL базы данных не используют общий формат запроса (как SQL в реляционных
базах данных). Каждое решение использует собственную систему запросов.

Сравнение SQL и NoSQL

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

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

В этом и кроется главное отличие реляционных SQL баз данных и нереляционных
NoSQL баз данных.

Базы данных SQL

Базы данных SQL используют язык структурированных запросов (structured query
language) для определения данных и манипулирования ими.

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

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

Базы данных NoSQL

В отличие от своего конкурента, NoSQL имеет динамическую схему для
неструктурированных данных. Сами данных хранятся множеством способов:

  • ориентированы на столбец (column-oriented)
  • ориентированы на документ (document-oriented)
  • построены на основе графа (graph-based)
  • организованы по схеме ключ-значение (key-value store)

Структура и тип хранящихся данных

SQL/реляционные базы данных требуют наличия однозначно определённой
структуры хранения данных, а NoSQL базы данных таких ограничений не ставят.

Традиционные реляционные базы данных SQL хранят данные в таблицах, где каждая строка
представляет отдельный элемент данных, а столбец характеризует один из параметров
элемента данных. По сути, строка данных таблицы плоский объект со своими свойствами
(столбцами). При этом каждый столбец несет в себе единицу информации/свойства,
и все свойства вместе образуют объект данных (строку).

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

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

Гибкость

В традиционных базах данных всё четко разложено по полочкам. Сначала определяем
модель (описываем структуру таблицы, какие поля, какие типы данных, размеры и т.д.)
и уже потом вводим данные. При этом вводить в столбец строки мы можем только данные,
которые соответствуют определению столбца (его типу и размеру). Если захотим добавить
новое поле, нам придется останавливать работу с таблицей и менять ее схему. Что может
занять очень много времени. Да и вообще что бы внести большие изменения в структуру,
неплохо было бы останавливать работу всех клиентов с базой данных. В NoSQL с этим
проще, схемы данных или динамические или вообще отсутствуют. Можно добавить данные
буквально на лету не внося изменения в схему данных.

Гибкость NoSQL заключается:

  • Можно создавать документы, не предопределяя их структуру
  • Каждый документ может иметь свою уникальную структуру
  • Синтакс может меняться в зависимости от базы данных
  • Можно добавлять новые поля и менять старые по мере продвижения

Масштабируемость

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

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

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

Надёжность

SQL базы данных однозначно надёжнее.

Поддержка

Для SQL существует больше готовых решений и известных проблем, что связано
с возрастом РСУБД.

Скорость

Многие NoSQL базы данных выигрывают в скорости.
Например, MongoDB очень хорошо оптимизирован для простых запросов.

Заключение сравнения

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

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

Если данные хорошо структурированы и структура данных меняется медленно, при этом
объем данных растет не лавинообразно то традиционные реляционные базы данных
подойдут больше.

Мас­шта­би­ро­ва­ние SQL и NoSQL

Пар­ти­ци­о­ни­ро­ва­ние (partitioning)

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

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

Репли­ка­ция (replication)

Репли­ка­ция — это син­хрон­ное или асин­хрон­ное копи­ро­ва­ние дан­ных между несколь­кими
сер­ве­ра­ми. Веду­щие сер­вера назы­вают масте­рами (master), а ведо­мые сер­вера —
слэй­вами (slave). Мастера исполь­зу­ются для изме­не­ния дан­ных, а слэйвы — для
счи­ты­ва­ния. В клас­си­че­ской схеме репли­ка­ции обычно один мастер и несколько
слэй­вов, так как в боль­шей части веб-про­ек­тов опе­ра­ций чте­ния на несколько
поряд­ков боль­ше, чем опе­ра­ций запи­си. Однако в более слож­ной схеме репли­ка­ции
может быть и несколько масте­ров.

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

Шар­динг (sharding)

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

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

https://medium.com/xplenty-blog/the-sql-vs-nosql-difference-mysql-vs-mongodb-32c9980e67b2
https://web-creator.ru/articles/partitioning_replication_sharding
https://medium.com/devschacht/node-hero-chapter-5-dd79607858f2
http://wisedata.ru/2016/04/13/rec-sql-nosql-whatdif/
https://tproger.ru/translations/sql-nosql-database-models/

Clone this wiki locally