Базы данных (БД) существуют с первых дней программирования, а появились они ещё раньше. Это — неотъемлемые части любых приложений. Хорошо спроектированная БД — это один из важнейших компонентов, влияющих на производительность программных проектов. Из-за этого множество архитекторов программных решений исследовали массу подходов к управлению данными, пытаясь выяснить то, какие из этих подходов работоспособны в определённых сценариях, а какие — нет. Выбор подходящей архитектуры БД обычно сводится к выбору между SQL и NoSQL, между реляционными и нереляционными базами данных. А иногда в одном проекте используют и то, и другое. В этой статье мы сделаем краткий обзор баз данных, поговорим об их истории, постараемся разобраться с тем, что собой представляют базы данных SQL и NoSQL, выясним ключевые различия между ними. База данных — это центральный блок приложения, который содержит все данные, касающиеся различных компонентов приложения. Это могут быть, например, конфигурационные данные, сведения о самом приложении, сведения о пользователях, данные, принадлежащие пользователям. Если попытаться описать сущность баз данных более формально, то получится следующее: База данных — это компьютеризованная система, которая хранит организованную информацию. База данных — это организованная коллекция данных, устройство которой позволяет обеспечить лёгкий доступ к данным. Для управления базами данных используются системы управления базами данных (СУБД, Database Management Systems, DBMS). Обычно базы данных делят на два вида: Нереляционные — NoSQL. Реляционные — SQL. Идея, лежащая в основе баз данных, появилась задолго до создания компьютеров. Она представлена шкафами, в которых хранились документы, и библиотеками. До появления баз данных такие хранилища документов были лучшим из того, что тогда существовало. С развитием компьютеров развивались и решения для хранения данных. Первой архитектурой цифровой базы данных была, в 1960-х годах, навигационная база данных (Navigational Database). При работе с такими БД пользователям нужно было перемещаться по ним для того чтобы найти нужную им информацию. Существовали две основных модели данных, использовавшиеся в таких БД: иерархическая (hierarchical) и сетевая (network). Вскоре после этого, в 1970-х, Эдгар Кодд, инженер из IBM, опубликовал статью о системе реляционных баз данных. Его идеи привели к революции в обработке данных, так как данные рассматривались как «объекты». Этот подход, в сочетании с возникновением объектно-ориентированных языков программирования, сделал возможным разработку приложений, основанную на данных. Это показало программистам то, как одни данные связаны с другими, дав возможность связывать вместе разные «объекты», пользуясь различными типами отношений между объектами. В таких базах данных использовался язык запросов QUEL. А вскоре IBM сказала своё слово в сфере реляционных баз данных, представив System R. Эта система, кроме прочего, сделала гораздо эффективнее навигацию по данным, их создание и фильтрацию. Это была первая СУБД, которая использовала SQL (Structured Query Language, язык структурированных запросов). А в 1998 году, вскоре после того, как бурно развился интернет и упала стоимость хранилищ данных, появилось понятие NoSQL (not only SQL, не только SQL). NoSQL-базы данных были предназначены для более крупных объёмов данных, чем SQL-базы данных. Для таких данных, которые сложно структурировать, используя реляционный подход. Это позволило быстрее обрабатывать более масштабные наборы данных, имеющих различную структуру. Базы данных NoSQL были гибче, чем типичные SQL-базы данных. Как уже было сказано, SQL-базы данных используют структурированный язык запросов (SQL) для управления данными, для их обработки, хранения, обновления, удаления. В реляционных хранилищах данных используются реляционные системы управления базами данных (РСУБД, Relational Database Management Systems, RDBMS). В РСУБД данные хранятся в табличном формате. Таблица — это базовая единица базы данных, она состоит из строк и столбцов, в которых хранятся данные. Таблицы — это самый часто используемый тип объектов баз данных, или структур, которые в реляционной БД хранят данные или ссылки на них. Среди других типов объектов баз данных можно отметить следующие: Представления (views) — виртуальные представления данных, собранных из одной или нескольких таблиц базы данных. Индексы (indexes) — таблицы, используемые для поиска данных, помогающие ускорить соответствующие возможности БД. Отчёты (reports) — они состоят из данных, полученных из одной или большего количества таблиц. Обычно они представляют некое подмножество данных, выбранных из БД на основе каких-то критериев поиска. Исследуем то, что называется реляционной моделью данных. Если попытаться сохранить данные об учителях и о классах, в которых они ведут занятия, то у нас получится (учитывая то, что это — простой пример) две таблицы. Одна — для учителей, вторая — для классов. Учитель может вести занятия в нескольких классах, а в одном классе занятия могут вести несколько учителей Итак, в этом примере имеется две таблицы. Одна содержит данные об учителе (Teacher), а вторая — о классе (Class). В таблице Teacher имеются следующие атрибуты/столбцы: id — идентификатор конкретного учителя. first_name — имя учителя. last_name — фамилия учителя. email — адрес электронной почты учителя. class — внешний ключ (foreign key), который связывает ID конкретного класса с учителем. А в таблице Class имеются такие столбцы: id — идентификатор класса. class_name — название класса. class_subject — предмет класса. class_category — категория класса. teacher — внешний ключ, связывающий ID учителя с классом. Это — простой пример отношений таблиц, где имеется две таблицы, в каждой из которых имеются атрибуты, содержащие сведения об объекте. Эти два объекта связаны друг с другом с помощью связи многие-ко-многим (many-to-many). В РСУБД существуют и другие типы связей. Многие-ко-многим (many-to-many) — это связь между таблицами Teacher — Class, которую мы только что рассмотрели. Многие-к-одному (many-to-one) — это, например, отношения таблицы Student (представляющей ученика) и таблицы Class (представляющей класс). Ученик может входить в состав лишь одного класса. Один-ко-многим (one-to-many) — такая связь описывает ситуацию, обратную предыдущей, когда в состав одного класса может входить несколько учеников. Один-к-одному (one-to-one) — например, такая связь описывает взаимоотношения объекта Student (ученик) и Desk (парта). У каждого ученика имеется в точности одна парта, а одна парта принадлежит лишь одному ученику. SQL — это язык, который позволяет удобно работать с РСУБД. SQL — это механизм взаимодействия с объектами базы данных, который позволяет воспользоваться тем, что заложено в неё на этапе её проектирования. Существуют различные подмножества команд SQL, в их состав, кроме прочих, входят следующие: Язык описания данных (Data Definition Language, DDL) — это команды, которые ещё называют командами описания данных, так как они используются при описании структуры таблиц баз данных. Язык управления данными (Data Manipulation Language, DML) — это команды, которые используются для управления данными в существующих таблицах путём добавления, изменения или удаления данных. В отличие от команд группы DDL, которые описывают то, как хранятся данные, DML-команды работают в уже существующих таблицах, описанных с помощью DDL-команд. Язык запросов данных (Data Query Language, DQL) — эта группа состоит всего из одной команды — SELECT, которая используется для получения необходимых данных из таблиц. Эту команду иногда включают в состав команд группы DML. Язык для осуществления административных функций (Data Control Language, DCL) — команды из этой группы применяются для управления пользователями, для предоставления или отмены доступа к базе данных. Язык для управления транзакциями (Transaction Control Language, TCL) — это команды, используемые для изменения состояния неких данных. Например — это команда COMMIT, заканчивающая текущую транзакцию с сохранением изменений в базе данных, или команда ROLLBACK, заканчивающая текущую транзакцию с отменой изменений в базе данных. Рассмотрим некоторые инструкции SQL, которые используются чаще всего. Команда CREATE используется для создания новой базы данных или новой таблицы. В этом примере мы создаём базу данных School, а потом создаём таблицу Teacher с атрибутами id, first_name, last_name, email и phone_number: Команда SELECT позволяет выбирать данные из таблиц. В этом примере мы получаем поля first_name и last_name из каждой строки таблицы Teacher: Команда DELETE удаляет строки из таблиц. Здесь мы удаляем из таблицы Teacher все строки, поле last_name которых содержит значение Banks: Команда INSERT INTO позволяет вставлять данные в таблицы. В этом примере в таблицу Teacher вставляется новая запись: Команда UPDATE позволяет обновлять данные строк в таблицах. Здесь мы обновляем данные в строках таблицы Teacher, поле last_name которых содержит Bankss: Как уже было сказано, NoSQL — это сокращение от not only SQL (не только SQL). Этим термином обозначают базу данных любого типа, которая хранит информацию не так, как хранят её РСУБД. NoSQL-базы данных отлично подходят для многих современных приложений, которым нужны гибкие, масштабируемые, высокопроизводительные базы данных, обладающие широким набором функциональных возможностей. Среди таких приложений — проекты из мобильной и веб-сферы, компьютерные игры. Возможности NoSQL-баз данных позволяют таким проектам давать своим пользователям наилучшие впечатления от работы с ними. Причина роста популярности NoSQL-баз данных, в основном, кроется в необходимости работы с данными, которые имеют самую разную структуру и самые разные размеры. Это могут быть структурированные (structured), полуструктурированные (semi-structured) и полиморфные (polymorphic) данные. При работе с такими данными определить схему данных практически невозможно. NoSQL, кроме того, даёт разработчику большую гибкость в тех случаях, когда ему нужно быстро адаптировать систему к изменениям. Например — это характерно для стартапов. NoSQL-базы данных предлагают пользователям API c широкими функциональными возможностями, а так же — типы данных, спроектированные специально для определённых моделей данных. Базы данных NoSQL, кроме того, легче, чем БД SQL, поддаются масштабированию, так как NoSQL-БД могут масштабироваться горизонтально. Делается это путём добавления дополнительных узлов при возникновении необходимости обрабатывать больше трафика, чем обычно. Это упрощает и расширение мощности в ситуациях пиковых сетевых нагрузок, и её сокращение в случаях, когда трафика не очень много. Это улучшает масштабируемость приложений. Это не значит, что SQL-базы данных не поддерживают горизонтальное масштабирование. При работе с РСУБД это, просто, делается сложнее. SQL-хранилища, в основном, масштабируют вертикально, то есть — давая больше вычислительной мощности серверу, на котором работает SQL-база данных. NoSQL-БД, кроме того, проще в работе с точки зрения программистов. А именно, программисты могут быстро приспосабливаться к изменениям БД, им не приходится забираться в слишком глубокие дебри в случаях, когда в базе данных нужно что-то изменить. За эти плюсы, правда, приходится платить. Например, если нужно нормализовать NoSQL-данные, понадобится написать скрипт, который перебирает все записи и обрабатывает их, изменяя их структуру. Это — рискованная операция, так как если в систему внесено слишком много изменений при выходе её новых релизов и при исправлении ошибок, может оказаться так, что в БД окажутся полиморфные данные, а значит — работа скрипта может окончиться неудачно. Существует множество типов NoSQL-баз данных, но к основным можно отнести лишь четыре. А другие либо попадают в эти категории, либо представляют собой некую их комбинацию. Базы данных типа «ключ-значение» (key-value database) — это простейшая БД NoSQL, где у каждой записи есть ключ, а так же — значение, связанное с этим ключом. Подобные БД пригодятся в случаях, когда имеются большие наборы данных, по которым нужно быстро производить поиск. В таких базах данных управление ключами — это жизненно важная задача, так как каждое значение связано с уникальным ключом. В таких базах данных все данные хранятся в одном и том же пространстве имён. А те, кому нужно больше гибкости в логическом разделении данных, обычно используют документоориентированные базы данных. Документоориентированные базы данных (document-oriented database) — так называются базы данных, каждая запись которых представляет собой документ, содержащий поля и значения. Формат описания таких документов похож на JSON, XML или на двоичное представление формата JSON. Данные в таких БД организованы в коллекции (Collections), которые аналогичны таблицам в РСУБД. В одной коллекции обычно хранят данные, у которых есть что-то общее. Например, в БД сайта интернет-магазина могут быть следующие коллекции: Товары, Заказы, Пользователи. Каждая из этих коллекций хранит данные, соответствующие её пространству имён. Так, в коллекции Товары будут документы, связанные с товарами. То же самое можно сказать и о коллекциях Заказы и Пользователи. Колоночные базы данных (wide-column database) — в таких БД для хранения данных используются таблицы, строки и столбцы (колонки). Но, в отличие от реляционных баз данных, имена и форматы столбцов в одной и той же таблице могут отличаться. Колоночные NoSQL-базы данных, не смотря на это, используют концепцию столбца, но при этом чтение или запись строки данных состоит из чтения или записи отдельных столбцов. Столбец сохраняется в БД лишь тогда, когда в нём имеется элемент данных. К каждому элементу данных можно обратиться по ключу строки. Но выполнение запросов значений работает быстро — как запросы по индексу в РСУБД, а не так, как медленные просмотры таблиц в РСУБД. Графовые базы данных (graph database) — это БД, которые хранят данные в узлах и рёбрах графов. Обычно данные о неких сущностях хранят в узлах, а сведения об отношениях между узлами хранят в рёбрах. Графовые базы данных созданы специально для того, чтобы хранить сведения о взаимоотношениях между сущностями и чтобы работать с этими сведениями. Отношения — это центральный элемент графовых баз данных. И ценны эти БД в основном тем, как они позволяют работать со сведениями об отношениях. С ребром, обозначающим отношение, всегда связан начальный узел, обозначающий сущность, конечный узел, тип отношения, направление. Ребро может описывать отношения типа родитель-потомок, действия, отношения владения ресурсами и прочее подобное. При этом количество и тип отношений, которые может иметь узел, не ограничено. Сейчас мы уже можем исследовать множество различных аспектов реляционных и нереляционных подходов к хранению данных. Пришло время сравнить их по разным показателям. SQL: масштабируется вертикально. То есть — путём увеличения производительности за счёт использования более мощных серверов. SQL-БД сложнее масштабировать, чем NoSQL-БД. NoSQL: масштабируется горизонтально. То есть — путём добавления дополнительных узлов к уже существующим, использующимся узлам. Это упрощает масштабирование — при необходимости можно быстро как повысить, так и понизить мощность системы. Это, кроме того, означает, что владелец NoSQL-БД может увеличивать её мощность практически неограниченно. SQL: эти БД не дают пользователю особой гибкости. Для работы с ними сначала надо спроектировать схему базы данных. А если в систему нужно внести какие-то изменения, например — добавить к записям новое свойство/столбец, придётся добавлять этот столбец к каждой строке. Это — ресурсозатратная и длительная операция. NoSQL: эта технология даёт гораздо больше гибкости, чем её «старший брат». Здесь нет фиксированного количества столбцов, NoSQL-БД очень легко адаптируются к новым схемам данных. Программисту, кроме того, не нужно заранее создавать схему БД. Это ускоряет подготовку к работе систем, основанных на NoSQL. Правда, использование этой технологии может вылиться в дополнительные затраты времени в том случае, если для некоего проекта понадобятся достаточно жёсткие схемы данных. SQL: данные хранятся в таблицах. Каждая сущность имеет собственную таблицу, они связаны друг с другом с использованием реляционных механизмов. Отсюда и термин — «реляционная система управления базами данных». NoSQL: данные хранятся с использованием большего количества подходов, чем при использовании SQL-БД. В частности, доступны такие способы хранения данных, как база данных типа «ключ-значение», документоориентированная база данных, колоночная база данных, графовая база данных. SQL: эти БД следуют требованиям ACID. ACID — это сокращение от Atomicity (атомарность), Consistency (согласованность), Isolation (изолированность) и Durability (надёжность). NoSQL: эти БД следуют требованиям теоремы CAP. CAP расшифровывается как Consistency (согласованность), Availability (доступность) и Partition Tolerance (устойчивость к разделению). SQL: так как история SQL начинается в 1970-х, вокруг этой идеологии работы с данными сложилось обширное сообщество, готовое помочь тем, у кого возникают сложности. Наработан большой опыт применения SQL в самых разных проектах. Но при этом многие диалекты SQL являются либо собственностью неких компаний, либо связаны с отдельными большими компаниями, что означает некоторую их изоляцию. NoSQL: так как БД NoSQL гораздо моложе БД SQL, они отличаются меньшим сообществом, для которого характерна большая разобщённость из-за разных подходов, использующихся в разных NoSQL-базах данных. При этом такие БД пользуются поддержкой опенсорс-сообщества, у каждой из них есть детальное руководство, описывающее особенности её использования. SQL: SQL-базы данных обычно предназначены для решения широкого круга задач. Они используются в достаточно старых системах, в приложениях, нуждающихся в строгом контроле данных, там, где нужно выполнять большие и сложные запросы. Такие базы данных, кроме того, часто используются в финансовом секторе, так как транзакции, проводимые в таких БД, строго соответствуют требованиям ACID. NoSQL: NoSQL-базы данных тоже можно назвать универсальными, но они по-настоящему раскрываются в приложениях, которые работают с разными источниками данных, имеющих различную структуру. Это могут быть IoT-приложения, игры и прочее подобное. Если рассмотреть варианты использования разных типов NoSQL-БД, о которых мы говорили выше, то получится следующее: Документоориентированные базы данных: широкий круг задач. Базы данных типа «ключ-значение»: обработка больших объёмов данных, где применяются простые запросы на поиск данных (например — управление сессиями в крупномасштабных системах). Колоночные базы данных: обработка больших объёмов данных с предсказуемыми шаблонами запросов (работа с журналами, IoT). Графовые базы данных: анализ и просмотр отношений между связанными данными (обнаружение мошенничеств, рекомендательные системы). Благодарю всех, кто добрался до этого места. Мы поговорили о том, что собой представляют базы данных, исследовали возможности и варианты использования баз данных SQL и NoSQL, разобрали их ключевые различия. SQL-базы данных строже, они не такие гибкие, как NoSQL-БД. Но они отлично подходят для организации работы с данными, обращение с которыми требует единообразия и чётких схем данных. NoSQL-БД, с другой стороны, гораздо гибче, они дают возможность работать с разными структурами данных в различных сценариях. Это делает их универсальнее. Я совершенно уверен в том, что каждый из этих подходов отлично показывает себя в своей сфере. То есть — в общих сравнениях, в словах о том, что «одно лучше другого», смысла нет. Всё зависит от конкретной ситуации. Надеюсь, вы нашли эту статью информативной и подробной, что вам легко было её читать. Спасибо и до новых встреч! Мы в wunderfund.io занимаемся высокочастотной алготорговлей с 2014 года. Высокочастотная торговля — это непрерывное соревнование лучших программистов и математиков всего мира. Присоединившись к нам, вы станете частью этой увлекательной схватки. Мы предлагаем интересные и сложные задачи по анализу данных и low latency разработке для увлеченных исследователей и программистов. Гибкий график и никакой бюрократии, решения быстро принимаются и воплощаются в жизнь. Сейчас мы ищем плюсовиков, питонистов, дата-инженеров и мл-рисерчеров. Присоединяйтесь к нашей команде.