Реляционная модель в сравнении с документоориентированной моделью

Сравнение документированной и реляционной модели данныхНаиболее известной моделью данных на сегодняшний день, вероятно, является модель данных SQL, основанная на предложенной в 1970 году Эдгаром Коддом реляционной модели: данные организованы в отношения (именуемые в SQL таблицами), где каждое отношение представляет собой неупорядоченный набор кортежей (строк в SQL).

Реляционная модель была теоретической конструкцией, и многие сомневались, возможна ли ее эффективная реализация. Однако к середине 1980-х годов реляционные системы управления базами данных (relational database management system, RDBMS) и SQL стали оптимальными инструментами для большинства тех, кому нужно было хранить более или менее структурированные данные и выполнять к ним запросы. Господство реляционных БД длилось около 25-30 лет — целая вечность по масштабам истории вычислительной техники.



Истоки реляционных баз данных лежат в обработке коммерческих данных (business data processing), выполнявшейся в 1960-х и 1970-х годах на больших ЭВМ. С сегодняшней точки зрения их сценарии использования представляются до­вольно рутинными: обычно это была обработка транзакций (ввод транзакций, связанных с продажами или банковской деятельностью, бронирование авиабиле­тов, складирование товаров) и пакетная обработка (выставление счетов покупа­телям, платежные ведомости, отчетность).

С течением времени появилось немало других подходов к хранению данных и вы­полнению к ним запросов. В 1970-х и начале 1980-х годов основными альтернативами реляционной были сетевая (network model) и иерархическая модели, но реляционная все равно побеждала. Объектные базы данных появились в конце 1980-х — начале 1990-х годов и снова вышли из моды. В начале 2000-х появились базы данных XML, но нашли только узкое применение. Каждый из соперников реляционных БД наделал в свое время много шума, но ненадолго но ненадолго.

По мере значительного повышения мощности компьютеров и соединения их в сети цели их использования стали все более разнообразными. И что примечательно, при­менение реляционных БД распространилось на широкое множество сценариев дале­ко за пределами первоначальной обработки коммерческих данных. Работа большей части Интернета до сих пор обеспечивается реляционными БД: онлайн-публикации, дискуссионные форумы, социальные сети, интернет-магазины, игры, предоставля­емые как сервис (по модели SaaS), офисные приложения и многое другое.

 

Рождение NoSQL

Сейчас, в 2010-х, NoSQL — самая недавняя попытка свергнуть господство реляци­онной модели. Название NoSQL — неудачное, ведь на самом деле ничего не говорит об используемой технологии, изначально оно было предложено в 2009 году просто в качестве броского хештега в Twitter для семинара по распределенным нереляци­онным БД с открытым исходным кодом. Тем не менее термин задел за живое и быстро распространился в среде создателей интернет-стартапов и не только их. С хештегом #NoSQL сейчас связано несколько интересных систем баз данных, и его задним числом интерпретировали как «Не Только SQL» (Not Only SQL).

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

  • потребность в бо'льших возможностях масштабирования, чем у реляцион­ных БД, включая обработку очень больших наборов данных или очень большую пропускную способность по записи;
  • предпочтение свободного программного обеспечения вместо коммерческих продуктов;
  • специализированные запросные операции, плохо поддерживаемые реляци­онной моделью;
  • разочарование ограниченностью реляционных схем и стремление к более ди­намичным и Phillips J. Surprises in Our NoSQL Adoption Survey.

У каждого приложения свои требования, и оптимальная технология может раз­личаться в зависимости от сценария использования. А потому вероятно, что в ближайшем будущем реляционные БД будут продолжать задействовать наряду с множеством разнообразных нереляционных баз данных — об этой идее иногда говорят как о применении нескольких систем хранения данных в одном приложении (polyglot persistence).

 

Объектно-реляционное несоответствие

Большая часть разработки приложений сегодня выполняется на объектно-ориен­тированных языках программирования, что привело к всеобщей критике модели данных SQL: при хранении данных в реляционных таблицах необходим неуклю­жий промежуточный слой между объектами кода приложения и моделью таблиц, строк и столбцов БД. Эту расстыковку моделей иногда называют рассогласованием (impedance mismatch).

Фреймворки объектно-реляционного отображения (ORM), такие как ActiveRecord и Hibernate, снижают количество шаблонного кода, необходимого для слоя транс­ляции, но не в состоянии полностью скрыть различия между двумя моделями.

Например, рис. 1 иллюстрирует возможность выражать резюме (профиль в со­циальной сети LinkedIn) на языке реляционной схемы. Профиль в целом опре­деляется уникальным идентификатором, user_id. Такие поля, как first_name и last_name, встречаются ровно один раз для одного пользователя, так что их можно сделать столбцами в таблице users. Однако у большинства людей за время карьеры бывает больше одной работы (должности), а также могут меняться периоды обу­чения и число элементов контактной информации. Между пользователем и этими элементами существует связь «один-ко-многим», которое можно представить не­сколькими способами.

  • В обычной SQL-модели (до SQL:1999) в случае наиболее распространенного нормализованного представления должности образование и контактная инфор­мация помещаются в отдельные таблицы, со ссылкой на таблицу users в виде внешнего ключа, как показано на рис. 1.
  • В более поздних версиях SQL-стандарта добавлена поддержка для структуриро­ванных типов данных и данных в формате XML. Таким образом, многоэлемент­ные данные можно сохранять в отдельной строке с возможностью отправлять к ним запросы и совершать индексации по ним. Эти возможности поддержива­ются в разной степени БД Oracle, IBM DB2, MS SQL Server и PostgreSQL. Тип данных JSON также поддерживается в разной степени несколькими БД, включая IBM DB2, MySQL и PostgreSQL.
  • Третий возможный вариант — кодирование должностей, образования и контакт­ной информации в виде JSON- или XML-документа, сохранение его в текстовом столбце в базе данных с интерпретацией приложением его структуры и содер­жимого. Здесь отсутствует возможность использования БД для выполнения запросов к содержимому этого кодированного столбца.

Представление профиля LinkedIn с помощью реляционной схемы

Рис. 1. Представление профиля LinkedIn с помощью реляционной схемы. Фото Билла Гейтса любезно предоставлено «Вики-складом»

Для структур данных типа резюме, обычно являющихся самостоятельным до­кументом, вполне подойдет представление в формате JSON (пример 1). Пре­имущество данного формата в том, что он намного проще, чем XML. Эту модель данных поддерживают такие документоориентированные БД, как MongoDB 111RethinkDBCouchDB и Espresso.

  {
"user_id": 251,
"first_name": "Bill",
"last_name": "Gates",
"summary": "Co-chair of the Bill & Melinda Gates... Active blogger.",
"region_id": "us:91",
"industry_id": 131,
"photo_url": "/p/7/000/253/05b/308dd6e.jpg",
"positions": [
   {"job_title": "Co-chair", "organization": "Bill & Melinda Gates Foundation"},
   {"job_title": "Co-founder, Chairman", "organization": "Microsoft"}
],
"education": [
   {"school_name": "Harvard University", "start": 1973, "end": 1975},
   {"school_name": "Lakeside School, Seattle", "start": null, "end": null}
],
"contact_info": {
   "blog": "http://thegatesnotes.com",
   "twitter": "http://twitter.com/BillGates"
  }
}

Некоторые разработчики считают, что модель JSON снижает рассогласование меж­ду кодом приложения и слоем хранения. Однако, у JSON как формата кодирования данных тоже есть проблемы. Чаще всего отсутствие схе­мы рассматривается как преимущество, мы обсудим это в пункте «Гибкость схемы в документной модели» подраздела «Реляционные и документоориентированные базы данных сегодня» данной статьи.

У JSON-представления — лучшая локальность, чем у многотабличной схемы на рис. 1. Для извлечения профиля в реляционном примере необходимо выпол­нить несколько запросов (по запросу к каждой таблице по user_id) или запутан­ное многостороннее соединение таблицы users с подчиненными ей таблицами. В JSON-представлении же вся нужная информация находится в одном месте, и одного запроса вполне достаточно.

Связи «один-ко-многим» профиля пользователя с его должностями, местами обучения и контактной информацией означает древовидную структуру данных, а JSON-представление делает эту структуру явной (рис. 2).

Связи «один-ко-многим» формируют древовидную структуру

 Рис. 2. Связи «один-ко-многим» формируют древовидную структуру

 

Связи «многие-к-одному» и «многие-ко-многим»

В примере 1 элементы region_id и industry_id представляют собой идентифи­каторы, а не текстовые строки вроде "Greater Seattle Area" и "Philanthropy". Почему?

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

  • единообразный стиль и варианты написания в разных профилях;
  • отсутствие неоднозначности (например, в случае нескольких городов с одним названием);
  • удобство модификации — имя хранится только в одном месте, так что при не­обходимости можно легко поменять его во всей системе (например, в случае изменения названия города по политическим причинам);
  • поддержка локализации — возможность при переводе сайта на различные языки локализовать стандартизированные списки, так что географический регион и сфера деятельности будут отображаться на языке пользователя;
  • улучшенные возможности поиска — например, данный профиль может быть найден при поиске филантропов штата Вашингтон, поскольку в списке обла­стей может быть закодирован факт нахождения Сиэтла в штате Вашингтон (что далеко не очевидно из строки "Greater Seattle Area").

Хранить ли идентификатор или текстовую строку — вопрос дублирования данных. При использовании идентификатора значимая для людей информация (напри­мер, слово philanthropy — «благотворительность») хранится только в одном месте, а при ссылке на нее везде применяется ID (имеющий смысл только внутри этой базы данных). Однако при непосредственном хранении текста такая информация дублируется в каждой записи, задействующей эти сведения.

Преимущество идентификаторов состоит в том, что в силу отсутствия какого-либо смысла их для людей нет необходимости менять их в каких-либо случаях: ID спо­собен оставаться тем же самым даже при изменении информации, на которую он указывает. А все значимое для людей может понадобиться поменять в будущем — и если эта информация дублируется, то придется обновлять все имеющиеся копии. Данное обстоятельство приводит к избыточности записи и риску несоответствий (когда одни копии информации обновлены, а другие — нет). Идея исключения подобного дублирования лежит в основе нормализации баз данных.

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

К сожалению, нормализация этих данных требует связей «многие-к-одному» (множество людей живет в одной области или работает в одной сфере деятель­ности), которые плохо вписываются в документную модель. В реляционных БД считается нормальным ссылаться на строки в других таблицах по ID, поскольку выполнение соединений не представляет сложностей. В документоориентирован­ных БД для древовидных структур соединения не нужны, так что их поддержка часто очень слаба.

Если СУБД сама по себе не поддерживает соединения, то приходится эмулировать соединение в коде приложения с помощью нескольких запросов к базе данных. (В этом случае списки географических регионов и сфер деятельности, вероятно, настолько невелики и меняются настолько редко, что приложение может их хра­нить в памяти. Тем не менее база делегирует работу по выполнению соединения коду приложения.) 

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

  • Компании и школы в виде сущностей. В предыдущем описании элементы organization (компания, в которой работает пользователь) и school_name (место обучения) — просто строки. Могут ли они быть вместо этого ссылками на сущ­ности? Тогда у каждой компании может быть своя веб-страница (с логотипом, лентой новостей и т. д.); каждое резюме будет включать ссылки на упоминаемые в нем компании и школы, а также их логотипы и другую информацию (см. при­мер из LinkedIn на рис. 3).
  • Рекомендации. Допустим, вам нужно добавить новую возможность: создание поль­зователем рекомендации для другого пользователя. Рекомендации отображаются в резюме того пользователя, который их получил, вместе с именем и фотогра­фией рекомендующего. Если дающий рекомендации обновляет свою фотографию, то во всех его рекомендациях должна отображаться новая фотография. Следо­вательно, рекомендация должна ссылаться на профиль ее автора.

Название компании — ссылка на сущность для этой компании

Рис. 3. Название компании — не просто строка, а ссылка на сущность для этой компании. Снимок экрана с LinkedIn.com


Рисунок 4 иллюстрирует необходимость связей «многие-ко-многим» для этих новых возможностей. Данные внутри каждого пунктирного прямоугольника можно сгруппировать в один документ, но ссылки на компании, школы и других пользо­вателей должны быть именно ссылками и потребуют соединений при выполнении запросов.

Расширение резюме с помощью связей «многие-ко-многим»

Рис. 4. Расширение резюме с помощью связей «многие-ко-многим»

 

Повторяется ли история в случае документоориентированных баз данных

Хотя связи «многие-ко-многим» и соединения регулярно используются в реля­ционных БД, документоориентированные базы данных и NoSQL возвращают нас к дискуссии о том, как лучше представить подобные отношения в БД. Эта дис­куссия намного старше, чем NoSQL, — на самом деле она возвращает нас к первым дням компьютеризованных систем баз данных.

В 1970-х годах самой популярной СУБД для обработки коммерческих данных была Система управления информацией (Information Management System, IMS) компа­нии IBM, изначально разработанная для управления запасами в космической про­грамме «Аполлон» и впервые выпущенная в коммерческий оборот в 1968 году. Она до сих пор используется и поддерживается, работая на операционной системе OS/390 на больших ЭВМ компании IBM.

Архитектура IMS применяет довольно простую модель данных под названием «иерархическая моДель», весьма схожую с JSON-моделью, которую задействуют документоориентированные БД. Все данные в ней представлены в виде дерева записей, вложенных в другие записи, что весьма напоминает структуру JSON на рис. 2.

Как и документоориентированные базы данных, IMS хорошо работает в случае связей «один-ко-многим», но со связями «многие-ко-многим» дела у нее обстоят хуже и она не поддерживает соединения. Разработчикам приходится определять, дублировать (денормализовать) ли данные или вручную разрешать ссылки одной записи на другую. Эти проблемы 1960-х и 1970-х годов были очень похожи на те проблемы, с которыми сталкиваются разработчики документоориентированных баз данных сегодня.

Для устранения ограничений иерархической модели было предложено множество решений. Два наиболее известных — реляционная модель (ставшая впоследствии SQL и завладевшая всем миром) и сетевая модель (сначала имевшая множество поклонников, но впоследствии канувшая в Лету). «Великий спор» между двумя лагерями длился большую часть 1970-х.

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

 

Сетевая модель

Сетевая модель была стандартизирована комитетом «Конференция по языкам систем обработки данных» (Conference on Data Systems Languages, CODASYL) и реализована несколькими разными производителями БД. Она известна также под названием модели CODASYL.

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

могла быть одна запись для области "Greater Seattle Area" со ссылкой на нее для каждого живущего там пользователя. Благодаря этому появлялась возможность моделировать связи «многие-к-одному» и «многие-ко-многим».

Ссылки между записями в сетевой модели представляли собой не внешние клю­чи, а скорее нечто напоминающее указатели в языках программирования (хотя и хранящиеся на диске). Единственный способ обращения к записи заключался в следовании от корневой записи по этим цепочкам ссылок. Такой путь назывался путем доступа (access path).

В простейшем случае путь доступа напоминает обход связного списка: начинаем с головного элемента списка и просматриваем по одной записи за раз до тех пор, пока не найдем нужную. Но в мире связей «многие-ко-многим» к одной записи может вести несколько различных путей, и работавшим с сетевой моделью про­граммистам приходилось держать в голове эти различные пути доступа.

Выполнение запросов в модели CODASYL представляло собой перемещение указателя по БД с помощью итерации по спискам записей и следования по путям доступа. Если у записи было несколько родительских записей (то есть несколько

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

Хотя в 1970-х годах ручной выбор путей доступа позволял использовать чрезвы­чайно ограниченные аппаратные возможности (например, накопители на магнитной ленте с исключительно медленным поиском) наиболее эффективным образом, это приводило к сложному и негибкому коду для обновления БД и выполнения запросов к ней. Как в иерархической, так и в сетевой модели, если путь доступа к необходимым данным был вам неизвестен, то вы оказывались в сложном положении. Чтобы изме­нить пути доступа, приходилось пробираться сквозь завалы написанного вручную кода запросов и переписывать его для новых путей доступа.

 

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

Реляционная модель, напротив, выставляла все данные напоказ: отношение (таб­лица) — просто набор кортежей (строк), вот и все. Никаких лабиринтообразных вложенных структур, никаких запутанных путей доступа, необходимых для про­смотра данных. Можно прочитать любую строку в таблице или даже все строки, выбирая те, что соответствуют произвольному условию. Можно прочитать конкрет­ную строку путем объявления некоторых столбцов ключом и выполнения поиска по этому ключу. Можно вставить новую строку в любую таблицу, не беспокоясь о связях по внешним ключам с другими таблицами1.

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

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

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

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

запросов, и все использующие БД приложения смогут извлечь из него выгоду. Если оптимизатора запросов у вас нет, то будет легче вручную написать код путей доступа для конкретного запроса, чем создавать универсальный оптимизатор, — но в долгосрочной перспективе универсальное решение имеет преимущество.

 

Сравнение с документоориентированными базами данных

Документоориентированные базы данных снова возвращаются к иерархической мо­дели в одном нюансе — сохранении вложенных записей (связей «один-ко-многим», таких как positions, education и contact_info на рис. 1) внутри их родительской записи вместо отдельной таблицы.

Однако в вопросе представления связей «многие-к-одному» и «многие-ко-многим» реляционные и документоориентированные базы данных, по существу, не отли­чаются: в обоих случаях обращение к соответствующему элементу происходит с помощью уникального идентификатора, именуемого внешним ключом (foreign key) в реляционной модели и ссылкой на документ (document reference) в документной модели. Этот идентификатор разрешается во время чтения с помощью соеди­нения или дополнительных запросов. До сих пор документоориентированные БД не следуют пути, проложенному CODASYL.

 

Реляционные и документоориентированные базы данных сегодня

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

Основные доводы в пользу документной модели данных — гибкость схемы, лучшая производительность вследствие локальности и большая близость к применяемым структурам данных (для некоторых приложений). Реляционная модель отвечает на это лучшей поддержкой соединений, а также связей «многие-к-одному» и «многие- ко-многим».

 

Какая из моделей приводит к более простому коду приложения

Если структура данных в приложении — документоподобная (то есть представ­ляет собой дерево связей «один-ко-многим», причем обычно все дерево загру­жается сразу), то использование документной модели, вероятно, будет хорошей идеей. Реляционная методика расщепления (shredding) — разложения докумен­топодобной структуры на множество таблиц (таких как positions, education

и contact_info на рис. 1) — может привести к запутанным схемам и чрезмерно усложненному коду приложения.

У документной модели есть свои ограничения: например, нельзя непосредственно ссылаться на вложенный элемент внутри документа, приходится говорить что-то вроде «второй элемент списка должностей для пользователя 251» (очень напоми­нает пути доступа в иерархической модели). Однако если вложенность документов не слишком велика, то это обычно не представляет проблемы.

Плохая поддержка соединений в документоориентированных базах данных может быть, а может и не быть проблемой, в зависимости от приложения. Например, связи «многие-ко-многим» могут никогда не понадобиться в аналитическом при­ложении, использующем документоориентированную БД для записи времени наступления событий.

Однако если в приложении используются связи «многие-ко-многим», то доку­ментная модель представляется менее привлекательной. Количество необходимых соединений можно снизить путем денормализации, но коду приложения понадо­бится выполнять дополнительную работу по поддержанию денормализованных данных в согласованном состоянии. Соединения эмулируются в коде при­ложения с помощью нескольких запросов к БД, но это усложняет приложение и обычно работает медленнее, чем выполняемое специализированным кодом СУБД соединение. В подобных случаях применение документной модели может привести к намного более сложному коду приложения и снижению производи­тельности.

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

 

Гибкость схемы в документной модели

Большинство документоориентированных БД, а также реляционные БД с поддерж­кой JSON не навязывают какой-либо схемы для данных в документах. Поддержке XML в реляционных БД обычно сопутствует необязательная проверка схемы. Отсутствие последней означает, что в документ можно добавлять произвольные ключи и значения, и при чтении клиенты не будут уверенны в том, какие поля могут содержать документы.

Документоориентированные БД обычно называют бессхемными (schemaless) или неструктурированными. Но это название может ввести в заблуждение, ведь читающий данные код обычно предполагает наличие у последних определенной структуры — то есть какая-то неявная схема все равно есть, но она не навязывается базой. Более точным было бы название schema-on-read (схема при чтении:

структура данных неявна и их интерпретация происходит при чтении), в отличие от schema-on-write (схема при записи: традиционный подход реляционных БД, при котором имеется явная схема и база гарантирует, что все записываемые данные ей соответствуют).

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

Различие между этими подходами особенно заметно в ситуациях, когда приложе­нию необходимо изменить формат его данных. Например, допустим, что в насто­ящий момент мы храним полное имя пользователя в одном поле и нам хотелось бы хранить имя и фамилию отдельно. В документоориентированной БД можно было бы просто начать писать новые документы с новыми полями и создать код в приложении, который обрабатывает случай чтения документов в старом формате. Например:

if (user && user.name && !user.first_name) {
   // В записанных до 8 декабря 2013 года документах нет поля first_name
   user.first_name = user.name.split(" ")[0];
}

С другой стороны, в схемы базы данных со статической проверкой типов обычно приходится выполнять миграцию примерно следующим образом:

ALTER TABLE users ADD COLUMN first_name text;
UPDATE users SET first_name = split_part(name, ' ', 1); -- PostgreSQL
UPDATE users SET first_name = substring_index(name, ' ', 1); -- MySQL

Об изменениях схемы обычно говорят как о медленных и требующих простоя системы. Это не совсем верно: большинство реляционных БД выполняют оператор ALTER TABLE за несколько миллисекунд. СУБД MySQL — известное исключение: она копирует всю таблицу при выполнении команды ALTER TABLE, что означает минуты или даже часы простоя в случае изменения схемы большой таблицы — хотя суще­ствуют различные утилиты для обхода данного ограничения.

Оператор UPDATE на большой таблице будет выполняться медленно в любой базе данных, поскольку приходится перезаписывать все строки. Если это непри­емлемо, то приложение может оставить значение поля first_name равным NULL (по умолчанию) и заполнить его во время чтения, как в случае с документо­ориентированной БД.

Подход «схема при чтении» предпочтителен, если структура элементов набора раз­личается по какой-либо причине (то есть данные разнородны), например, в таких ситуациях:

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

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

 

Локальность данных и запросы

Документы обычно хранятся в виде единых непрерывных строк, закодированных в формат JSON, XML или их двоичную разновидность (например, формат BSON базы данных MongoDB). Если приложению часто требуется доступ ко всему до­кументу (например, для визуализации веб-страницы), то локальность хранилища дает определенные преимущества. Если данные разбиты по нескольким табли­цам, как на рис. 1, то понадобится несколько поисков по индексу для полного их извлечения, что потребует больше операций дискового поиска и займет больше времени.

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

Заслуживает упоминания то, что идея группировать вместе родственные данные в целях локальности не ограничивается документной моделью. Например, БД Spanner компании Google обеспечивает те же свойства локальности в реляци­онной модели данных, благодаря тому что схема способна объявить о необхо­димости чередования (вложенности) строк таблицы внутри родительской.

В СУБД Oracle может быть то же самое благодаря возможности под названием «многотабличные кластеризованные индекс-таблицы» (multi-table index cluster tables). Идея семейства столбцов (column-family) в модели данных Bigtable (используемой в СУБД Cassandra и HBase) тоже заключается в управлении ло­кальностью.

 

Постепенное сближение документоориентированных и реляционных баз данных

Большинство систем реляционных БД (кроме MySQL) поддерживают XML с середины 2000-х годов, включая функции для выполнения локальных изме­нений в XML-документах и возможность индексации последних и выполнения запросов к ним. Это позволяет приложениям задействовать модели данных, очень похожие на те, которые были бы у них при использовании документо­ориентированной БД.

У СУБД PostgreSQL, начиная с версии 9.3, MySQL, начиная с версии 5.7, и IBM DB2, начиная с версии 10.5, был примерно такой же уровень поддержки JSON-документов. Учитывая широкое использование JSON в веб-API, вполне вероятно, что другие реляционные базы данных пойдут по их следам и добавят поддержку формата JSON.

Что касается документоориентированных баз данных, RethinkDB поддерживает в своем языке запросов соединения, напоминающие реляционные, а некоторые драйверы MongoDB автоматически разрешают ссылки на БД. (По существу, та­ким образом производится клиентское соединение, хотя и более медленное, чем выполняемое в БД, поскольку при нем данные перемещаются по сети в два конца и оно менее оптимизировано.)

Похоже, что реляционные и документоориентированные БД становятся все более схожими, и это хорошо: их модели данных дополняют друг друга

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

Вас заинтересует / Intresting for you:

Модели данных и концептуальное...
Модели данных и концептуальное... 386 просмотров Ирина Светлова Thu, 11 Feb 2021, 14:18:45
Что такое базы данных? Назначе...
Что такое базы данных? Назначе... 4663 просмотров Ирина Светлова Mon, 28 Oct 2019, 05:41:34
Автономные базы данных: назнач...
Автономные базы данных: назнач... 445 просмотров Андрей Волков Mon, 08 Feb 2021, 10:31:32
Индексирование во временных ба...
Индексирование во временных ба... 847 просмотров Ирина Светлова Sun, 24 Mar 2019, 06:49:28
Войдите чтобы комментировать