NoSQL vs SQL, и при чем тут теорема CAP
Эта серия статей предназначена для стойких духом инженеров — в ней мы рассмотрим существующие NoSQL технологии, их особенности и отличия от классических реляционных SQL баз. Начнём же наш обзор.
Все современные технологии хранения данных можно разделить на следующие группы:
В этой статье мы рассмотрим общие различия между SQL и NoSQL.
Классика реляционных баз данных
Как всем нам известно, реляционная модель данных — это не что иное как набор таблиц, имеющих отношения (relations) друг с другом. Приводить полное определение в рамках этой статьи я, конечно же, не буду.
Придумал реляционную теорию баз данных в
Однако при всех своих достоинствах данный тип хранилищ обладает рядом неприятных особенностей:
— реляционные базы плохо масштабируются, с ними крайне сложно создавать распределенные хранилища;
— проектирование крупных баз с множеством компонентов требует значительных усилий. Это приведение сущностей к нормальным формам и сложности в отображении связей типа многие-ко-многим. Такие схемы тяжело читать и понимать их бизнес-применение;
— эволюция схемы данных почти всегда отстает от новых потребностей бизнеса. Часто она успевает устаревать еще до выпуска новой фичи. Миграция на обновленную схему занимает безобразно долгие часы, в течение которых «сервер лежит».
Все эти сложности существуют по одной простой причине: реляционная модель была создана для хранения табличных данных. И для этих целей она прекрасно подходит. Но прошло уже почти полвека с момента изобретения модели реляций: за это время системы хранения данных давно успели вырасти из «простых табличек» в распределенных дата-монстров. Создавая свою теорию, господин Кодд явно не рассчитывал на такое.
Действие теоремы CAP в контексте SQL и NoSQL
В то время, как реляционные схемы полагаются на принципы ACID, все без исключения NoSQL хранилища опираются на другие принципы, описанные в теореме CAP. Для начала в ней утверждается, что любое хранилище данных имеет три базовых свойства:
— Согласованность данных (Consistency). То есть данные должны быть полными и непротиворечивыми (в том числе и во всех узлах кластера).
— Доступность (Availability). Грубо говоря, это скорость ответа сервера на наш запрос (для записи или чтения).
— Устойчивость к разделению (Partition tolerance). Это значит, что в случае разделения системы на несколько частей каждая из них, если она доступна, должна быть в состоянии работать автономно, отдавая корректный отклик и предоставляя свои данные. Обрыв связей в кластере не должен влиять на итоговую работу.
Теорема CAP сообщает нам, что из этих трёх компонентов мы можем получить только два. Либо в той же пропорции 2:1 балансировать между этими составляющими: улучшение характеристик по одному из свойств влечёт за собой ухудшение в каком-то другом. Чтобы лучше понять силу этой теоремы, представьте себе распределенное хранилище, в котором вы пытаетесь без тормозов по производительности обеспечить 100% согласованные данные (на чтение и запись).
В условиях работы односерверной архитектуры, если сервер работает, то он доступен. А база данных на нём, если руки проектировщика растут из плеч, — согласована. Беспокоиться об устойчивости к разделению узла нет никакой необходимости, так как система физически является неделимой. Именно в таких условиях возникли классические реляционные системы. И поэтому они неустойчивы к разделению: лишено смысла проектировать разделяемую структуру в неделимом окружении.
На самом деле, практически все NoSQL технологии были рождены с целью решить проблему устойчивости к разделению, то есть эффективно работать на кластерах. Реляционная модель не в состоянии справиться с этой задачей, так как была создана для других целей и в других условиях. У вас не получится «просто отпилить парочку-тройку таблиц или спокойно их партицировать в соседний кластер», а потом отправиться пить кофе-чай. Welcome to Hell.
Хранилища NoSQL по своей природе могут быть легко разделены на кластер из-за специфической структуры хранения данных.
Истинная суть теоремы CAP проявляется именно в условиях распределенной системы. Очевидно, что создавать неустойчивый к разделению кластер — лишено какой-либо практической пользы. То есть кластер априори должен создаваться устойчивым к разделению. Понимание этого факта позволяет нам увидеть теорему CAP в новом свете: из согласованности и доступности можно выбрать только что-то одно — или же использовать разумный компромисс между этими двумя пунктами (а не тремя, как можно подумать из оригинального определения).
Вторая задача, которую пытаются решить идеологи NoSQL технологий, — повышение доступности, то есть получать быстрый ответ сервера. За счет чего эта задача решается в агрегатных и графовых базах, я напишу в следующих статьях цикла.
Больше информации по этим вопросам можно найти, изучив понятие итоговой целостности и подхода BASE.
Общие свойства технологии NoSQL
Ниже я напишу о самых существенных на мой взгляд общих свойствах всех NoSQL технологий.
1. NoSQL противопоставляются реляционным базам (как можно догадаться из названия). Если подытожить всё сказанное выше в пояснениях к теореме CAP, то мы получим следующую картину. Условия существования баз данных изменились. В результате возникли новые проблемы, справиться с которыми классические SQL базы не могли. За короткий период времени родились целые семейства баз данных, целенаправленно отказавшихся от реляционной структуры. Мы получили ориентацию на кластеры, быстрый ответ сервера и итоговую целостность.
2. NoSQL имеют неявную схему данных — этот факт часто пугает инженеров, привыкших работать со строгой схемой реляционных баз. Я часто слышу аргументацию в стиле «в такую базу можно писать что угодно в любом порядке, это же хаос». На самом деле бардак можно устроить в любом месте, было бы желание. Но все данные, которые вы пишите, а потом читаете, имеют определенную структуру. У вас есть именованные поля, в них хранятся данные определенного типа. Проблема состоит лишь в том, что теперь контроль за вашей структурой перекладывается с СУБД на приложение: вы сами можете установить в нём любые правила валидаций.
Особый интерес вызывает ситуация, когда с базой работают сразу несколько приложений, каждое из которых хочет писать и читать неявно-структурированные данные. Очевидно, что рано или поздно между ними возникнет конфликт форматов. В этом случае можно поступить по-разному:
— разграничить зоны ответственности каждого приложения: в разные области схемы данных должны иметь доступ разные приложения;
— использовать идею шаблона Прокси: обернуть нашу драгоценность (базу) в отдельное приложение и общаться с ним через веб-сервисы.
Выделить проксирующий слой полезно и внутри одиночного приложения, таким образом вы получаете некоторую страховку от кривых рук джунов, норовящих производить запросы в базу напрямую.
Ещё одна отличительная особенность неявной схемы данных заключается в её эволюционности. Вы можете вносить коррективы в структуру данных на лету, в ногу с потребностями бизнеса. В реляционных базах менять архитектуру — всегда накладно. Это физически тяжело. Например, ALTER TABLE занимает 8,5 часов, при которых сервер базы недоступен. Но ты знаешь, что Mongo (документная база) или Vertica (семейство столбцов), или Neo4j (графовая база) могли бы решить эту задачу за 0,0000x сек. И это удручает в работе с SQL базами.
Дело в том, что изменение формата новых данных в NoSQL не требует обязательного исправления старых записей. Такие базы просто пишут новую информацию в нужном нам виде.
Однако обратная сторона этой медали заключается в том, что вам всё ещё нужно уметь читать и интерпретировать нужным образом ранее записанную информацию «устаревших» форматов. Что можно сделать, чтобы уменьшить боль неминуемого рефакторинга NoSQL баз:
— относиться серьезно к неявной схеме данных еще на моменте ее проектирования;
— покрывать тестами вашу неявную схему данных в базе, проверяя все нужные форматы содержимого;
— не надеяться, что отказ от старых форматов и миграция на новые будет легче, чем в реляционной модели: использование неявной схемы данных не избавляет вас от этой боли. Перепроектирование границ агрегата или создание новых узлов графа из атрибутов существующих узлов ничуть не лучше классического ALTER в базе SQL: вам всё равно придётся последовательно обходить значительную часть записей базы и исправлять их.
На этой оптимистичной ноте статья подходит к концу. В следующий раз мы рассмотрим особенности агрегатного семейства.
Сердечно благодарю Славу Конашкова за технические консультации и помощь в написании материала.
P.S. Очень доходчиво и подробно теорема CAP описана в книге «NoSql: новая методология разработки нереляционных баз данных» (Прамодкумар Дж. Садаладж, Мартин Фаулер). Подход BASE и сравнение технологий NoSQL также можно посмотреть в книге «Графовые базы данных» (Ян Робинсон, Джим Вебер, Эмиль Эифрем).