При проектировании полного жизненного цикла Enterprise-приложений большое значение приобретает вопрос организации их доступа к данным. Тому есть ряд причин:
  • ценовые или иные политики поставщиков хранилищ данных регулярно меняются, но предприятия, использующие данные хранилища, не всегда согласны с этими изменениями;
  • с ростом самого предприятия и масштабов его ИТ-инфраструктуры существующие решения по хранению данных могут перестать удовлетворять его потребностям или финансовым возможностям;
  • технологии хранения данных развиваются, появляются новые средства, предназначенные для решения специализированных задач;
  • в рамках проектов Open Source вырастают дешевые или даже бесплатные альтернативы дорогим коммерческим решениям.

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

Проблему разделения бизнес-логики и работы с данными на уровне отдельного приложения решает широко известный и не раз описанный на «Хабрахабре» архитектурный шаблон Data Access Layer (DAL). Для того, чтобы этот шаблон можно было масштабировать до уровня всего предприятия, необходимо дополнить его рядом архитектурных принципов, которые рассматриваются в данной статье. Следование этим принципам позволит предприятию осуществлять контролируемую (управляемую) замену или добавлять технологии хранения данных в свою архитектуру ИТ.

Проблематика


Данный раздел более подробно описывает исходную проблематику и предпосылки, которые привели к разработке концепции DAL.

Необходимость работы со специализированными БД


В настоящее время классические реляционные СУБД (РСУБД) перестали быть единственным средством для решения задачи по хранению данных при разработке приложений. От универсальных СУБД происходит переход к специализированным. При этом специализация средств хранения идет по разным направлениям: по объему (класс Big Data), нагрузке (класс HighLoad), производительности (классы High Performance, Fast Data) и т. д.

Для архитектуры конкретного приложения входит в норму подбор средства или класса средств хранения под конкретную решаемую задачу. Для масштабных ИТ-систем оптимальным нередко становится одновременное использование нескольких БД различного типа в рамках одного приложения (гетерогенное хранение, рис. 1) для разных групп данных.


Рис. 1. Универсальные и специализированные базы данных

Например, для отдельных задач, в которых не требуется представлять в реляционной модели данные простой структуры, но при этом необходимо обеспечить повышенные требования к производительности и масштабируемости, могут применяться специализированные хранилища «ключ-значение» (key-value). Для иных специальных видов данных (document, photo, video, excel, text) и различных нефункциональных требований существует и широко используется масса других средств хранения с различными интерфейсами доступа (NoSQL).

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

Таким образом, современное предприятие с развитой ИТ-архитектурой все чаще сталкивается с необходимостью отхода от «единого золотого стандарта» применяемой СУБД (часто это БД компаний Oracle или Microsoft) и оказывается лицом к лицу с необходимостью обеспечивать инфраструктуру приложений в виде множества баз данных и хранилищ, в том числе класса NoSQL.

На уровне архитектуры приложений это ведет к появлению множества ранее недоступных возможностей по применению специализированных БД, что позволяет ускорять разработку, снижать стоимость сопровождения, обеспечивать принципиально новые возможности для бизнеса (если, конечно, новые возможности используются с умом). Например, использование кластерных БД с хранением в памяти (так называемых in-memory database, характерные представители — VoltDB или SAP HANA) может реализовать радикально отличающийся подход к решению задач бизнес-аналитики за счет ускорения вычислений на несколько порядков.

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

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

Воздействие внешних условий


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

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

Потребность в модернизации и технологическом развитии


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

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

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

Концепция Data Access Layer


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

Принцип управляемого специализированного хранения данных


Итак, разрабатываемая концепция должна отвечать поставленной проблематике:
  • обеспечивать возможность использования специализированных БД в ИТ-архитектуре предприятия одновременно с сохранением управляемости (например, за счет контроля их разнообразия и применения);
  • подготавливать бизнес-приложения к плавной и технологичной смене СУБД в случае обострения отношений с поставщиком СУБД или, возможно, из соображений технологической модернизации и технологического развития.

В основе концепции лежит принцип управляемого специализированного хранения данных, который вводит унифицированный и контролируемый способ доступа к различным данным для приложений (рис. 2).


Рис. 2. Принцип управляемого специализированного хранения данных

На уровне технологической политики предприятия определяется фиксированный набор классов данных, для которых в инфраструктуре предоставляются некоторые средства хранения. Каждый класс данных при этом предполагает специализированный интерфейс доступа (пока — на логическом уровне), оптимальный для данного класса. Например, для класса данных key-value интерфейс доступа должен предоставлять операции чтения и записи данных по ключу. А для класса данных «реляционная модель» интерфейс доступа представлен в виде некоторого фиксированного диалекта SQL.

Для каждого такого логического класса данных инфраструктура может предоставить средства хранения с разным уровнем обеспечения нефункциональных требований, который четко зафиксирован некоторым SLA (определяемым классом средств хранения).

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

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

Ограничение способа доступа к данным на уровне программной архитектуры




Рис. 3. Ограничение способа доступа к данным на уровне программной архитектуры

Еще один важный принцип DAL связан с механизмом обеспечения выбранного способа доступа к данным для бизнес-приложений (рис. 3). Теоретически достаточно было бы зафиксировать ряд ограничений доступа к данным на уровне архитектурной политики предприятия и контролировать соблюдение этих ограничений при проектировании и разработке информационных систем.

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

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

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

Вынос бизнес-логики из БД


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

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

Понятия


Этот раздел уточняет и детализирует модель объектов описания DAL, коротко введенную в предыдущем разделе.


Рис. 4. Понятийная модель концепции DAL

Концепция вводит несколько понятий (рис. 4):
  • класс данных;
  • средство хранения;
  • характеристика средства хранения;
  • класс средств хранения;
  • группа данных;
  • контейнер данных.

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

Класс данных


Определяет идеальную абстракцию данных, не зависящую ни от конкретных технологий, ни от ограничений реализуемости:
  • абстрактную («логико-математическую») модель самих данных (например, «набор реляционных отношений» или «набор пар ключ-значение»);
  • модель (или несколько моделей) доступа к данным и вычисления над данными (например, «реляционная алгебра» или MapReduce);
  • модель безопасности (например, «именованные контейнеры», «пользователи» и «права»);
  • модель структуры данных (например, «схема с описанием таблиц» или «перечень групп атрибутов»).

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

Структура данных


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

Средства хранения


Конкретные имеющиеся на рынке или развернутые на предприятии средства хранения (различные виды БД) предоставляют возможности одного или нескольких классов средств хранения для нескольких классов данных.

Характеристика средства хранения


Представляет собой какую-либо значимую числовую, качественную характеристику или бинарный признак средства хранения:
  • производительность чтения/записи;
  • масштабируемость;
  • работа в памяти (in-memory);
  • ограничения;
  • специализация (например, Big Data или Fast Data);
  • поддержка ACID-транзакций и т. д.


Класс средств хранения (SLA)


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

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

Группа данных


Данные в рамках конкретного приложения, по логике этого приложения принадлежащие к одному классу данных и требующие одного SLA; например, в приложении может быть выделена группа данных «справочники X», принадлежащая классу key-value и требующая быстрого чтения по ключу.

Контейнер данных


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

Структура Data Access Layer


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

Функции и границы DAL в ИТ-ландшафте предприятия


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


Рис. 5. Структура DAL в архитектуре предприятия

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

Принципы, применяющиеся при проектировании DAL


  1. Не ставится задача автоматического, безостановочного, не требующего затрат или мгновенного переключения работающей АС с одного средства хранения на другое. Проектировочные решения должны не полностью исключать (что долго и сложно), а существенно снижать зависимость логики приложения от средства хранения таким образом, чтобы значительно облегчить возможный переход. Нужно рассчитывать на разумный подход проектировщиков АС и понимание ими архитектурных принципов и целей, а потому не пытаться выстроить суперзащищенную техническую систему.
  2. При проектировании должны максимально использоваться готовые, уже существующие на рынке и стандартизованные средства и компоненты. Если предприятие хочет обеспечить максимальную независимость от вендоров, то предпочтительно использование Open Source продуктов и технологий, но только достаточно зрелых, с подобающим размером сообщества и примерами внедрений на ответственных предприятиях.
  3. Следует стремиться к простоте перевода существующих АС на DAL.
  4. Лучше наращивать возможности реализуемого DAL постепенно, итерационно. Первый шаг должен быть простым, дешевым и быстрым, направленным на решение наиболее актуальных задач (в частности, переносимость реляционных СУБД).
  5. Новый подход к управлению хранением может не ограничиваться техническими средствами, а включать, например, изменения в организационных механизмах предприятия в части управления инфраструктурой, а также в процессах проектирования и технического аудита АС.

Варианты размещения компонентов структуры DAL



Рис. 6. Варианты размещения компонентов структуры DAL

Структура DAL предполагает два варианта размещения модулей доступа к данным (рис. 6).
  1. В виде библиотеки, включаемой в состав приложения. В этом варианте необходима разработка разных видов модулей доступа для разных технологий разработки АС.
  2. В виде сетевого сервиса. Этот вариант предназначен для тех случаев, когда по каким-то причинам невозможна или нежелательна работа сервиса доступа к данным в виде библиотеки (например, ИС разработана на платформе, у которой нет библиотеки для работы с DAL). В таком варианте DAL доступен для любого приложения, способного работать с сетевыми сервисами по протоколу HTTP. Для этого способа размещения набор предоставляемых интерфейсов доступа к данным может быть ограничен.

Программные интерфейсы доступа к данным


Для реализации доступа бизнес-приложений к данным каждого класса следует отдавать предпочтение индустриальным стандартам и стандартам де-факто для программных интерфейсов доступа (API). Это позволит обеспечить не только максимально простую адаптацию существующих АС к работе с DAL, но и долгосрочную устойчивость слоя доступа к данным к последующим технологическим изменениям.

Программные интерфейсы доступа к данным (API), которые бизнес-приложения получают в пользование, могут различаться для разных базовых технологий приложений. Это оптимизирует разработку и соответствует стандартам де-факто для данной базовой технологии. Важно отметить, что такое разделение не нарушает общие принципы концепции унифицированного доступа к данным, поскольку — и это главное — сохраняется независимость приложения от конкретной используемой технологии БД. Например, для приложений, разработанных на Java, стандартным интерфейсом доступа к реляционным данным может быть принятый в Java-мире интерфейс JDBC, в то время как для приложений на C/C++ предоставляется интерфейс ODBC.

Ограничение диалекта SQL при работе через интерфейсы ODBC/JDBC



Рис. 7. Унификация и трансляция SQL

Для реляционных данных современные СУБД предоставляют большое количество специфических возможностей и диалектов языка SQL. Активное использование разнообразных инструментов в приложениях приводит к ухудшению их переносимости. Поэтому в рамках реализации DAL модуль доступа к реляционным данным на основе SQL должен специально ограничивать используемый диалект SQL таким образом, чтобы приложение в принципе не имело возможности завязаться на особенности конкретной СУБД (рис. 7).

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

Модуль доступа к РСУБД для приложений Java


Исходя из изложенных выше принципов проектирования, первым и наиболее актуальным модулем для реализации DAL является модуль доступа к реляционным данным. Несмотря на то, что, как было описано в проблематике, все чаще корпоративные бизнес-приложения пользуются потенциальными преимуществами в использовании NoSQL-БД, реляционные БД остаются наиболее широко применяемыми и востребованными видами средств хранения (зачастую просто потому, что большое количество прикладного ПО уже разработано в расчете именно на РСУБД).

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

Интерфейсы доступа к реляционным данным


Для Java-приложений широко распространены два стандартных интерфейса доступа к РСУБД:
  • доступ напрямую к реляционным данным через интерфейс JDBC и язык SQL;
  • доступ посредством объектной модели через объектно-реляционный адаптер JPA (Java Persistence API).

На практике приложения используют комбинацию этих двух способов доступа. Для изменения данных и чтения одиночных объектов часто используется JPA, а для сложных отчетов и выборок — SQL-запросы, выполняемые напрямую через JDBC-соединение или посредством специальных входов в JPA (так называемые native queries).

Видится целесообразным в качестве унифицированного интерфейса доступа зафиксировать именно эти два способа в совокупности. При этом необходимо, как было указано выше, явно ограничить используемый в прямых запросах диалект SQL некоторым «унифицированным» вариантом, поскольку JDBC и JPA native queries позволяют выполнять произвольные запросы в синтаксисе произвольной СУБД.

Конструктивная реализация модуля DAL для Java


Итак, модуль DAL для доступа Java-приложений к РСУБД должен предоставлять интерфейсы JPA и JDBC, но при этом ограничивать использование SQL только его «унифицированным» вариантом, чтобы при необходимости обеспечить максимально оперативный перевод на другую РСУБД.

Разработку модуля с такими требованиями можно было бы произвести самостоятельно, но оптимальный вариант — использовать для этого готовые программные компоненты с близкой функциональностью. В нашей компании при реализации DAL в качестве такого компонента после анализа ряда имеющихся готовых продуктов был выбран продукт JBoss Teiid, изначально предназначенный для федерирования (виртуализации) доступа к данным в масштабах предприятия (рис. 8).


Рис. 8. Конструктивная реализация модуля DAL для Java

Описанным выше требованиям DAL соответствуют следующие функции и свойства JBoss Teiid:
  • предоставление интерфейса JPA для приложений Java;
  • предоставление интерфейса JDBC для приложений Java;
  • использование собственного унифицированного диалекта SQL (на основе стандарта SQL-99);
  • трансляция собственного диалекта SQL в специфические диалекты поддерживаемых БД;
  • наличие коннекторов к большинству используемых РСУБД и простая расширяемость;
  • возможность работы как в режиме встроенного модуля, так и в режиме сетевого сервиса;
  • открытые исходные коды (Open Source), возможность бесплатного использования в коммерческих целях, развитое сообщество и примеры внедрения в крупных предприятиях.

Кроме того, использование Teiid открывает следующие дополнительные возможности:
  • объединение баз данных путем создания так называемой «виртуальной БД» (virtual DB, VDB) в настройках с помощью визуального дизайнера. Подобная «виртуальная БД» ассоциируется с реальными средствами хранения (не только реляционными);
  • эффективное выполнение «кросс-запросов» — SQL-запросов к «виртуальной БД», которые автоматически транслируются в SQL-запросы к реальным БД;
  • кеширование результатов запросов к «виртуальной БД».

Примеры использования DAL


В рамках изучения возможностей миграции на PostgreSQL наша компания провела пилотный проект по переводу одной из ИТ-систем с Oracle на эту СУБД. Объектом стала расчетная бэк-офисная система, построенная по принципу трехзвенной архитектуры. Большая часть бизнес-логики (основные расчеты) ИТ-системы находилась на уровне сервера приложений, часть логики (бухгалтерский учет) — в хранимых процедурах Oracle. При проектировании данной ИТ-системы в архитектуру изначально был заложен принцип доступа к данным через Data Access Layer. Этот слой был построен на основе технологии JPA с реализацией Hibernate.

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

Для организации гибридного доступа было подготовлено решение на основе JBoss Teiid: создана «виртуальная БД», объединившая в себе доступ к таблицам PostgreSQL и хранимым процедурам и таблицам учетной части в Oracle. Это позволило системе обращаться к двум СУБД как к единой базе. Поскольку приложение работало через DAL, все эти тонкости для него были экранированы. Также на уровне DAL были выполнены доработки по преобразованию специфичных для Oracle SQL-конструкций в поддерживаемые Teiid выражения. Эти доработки касались только работы с данными и никак не затронули бизнес-функционал системы. После выполнения доработок система успешно прошла модульное и функциональное тестирование.

Техническим подробностям миграции баз данных с Oracle на PostgreSQL был посвящен недавний пост моего коллеги Максима Трегубова.

Также подход организации доступа к данным через DAL сыграл положительную роль при модернизации ряда приложений нашей компании. В ходе модернизации различные журналы работы приложений (журналы аудита, взаимодействия с внешними системами и др.) были перенесены в архивное хранилище на основе Hadoop. Остальные данные приложений остались в оперативной реляционной СУБД. Так как доступ к данным журналов осуществлялся через отдельный компонент со своим API, замена средства хранения не повлияла на остальную функциональность приложения и не потребовала существенных доработок.

Заключение


Если предприятие хочет сохранить независимость от поставщиков конкретных решений для ИТ-инфраструктуры, то разработчикам ИТ-систем предприятия следует максимально абстрагироваться от специфики этих решений. Следование архитектурным принципам Data Access Layer позволит предприятию не быть заложниками проприетарных СУБД и выбирать наиболее подходящее по возможностям и стоимости решение для хранения данных. Помимо этого, у компании появится возможность использования новых технологий для работы с данными без значительных доработок АС.

Комментарии (18)


  1. eaa
    31.08.2015 16:08
    +1

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

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

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

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


    1. vmuravlev
      31.08.2015 18:03

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

      В том-то и дело, что у разработчиков все равно остаются средства для использования vendor-specific особенностей конкретной СУБД. Никто не мешает, например, при работе через JDBC использовать специфичные конструкции Oracle или MS SQL. Драйвер это пропустит. А вот при работе через DAL такого сделать не получится.

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


      Совершенно верно, и в статье об этом говорится: если мы выходим за рамки класса данных (например, переходим от реляционных данных к key-value), то приложение потребует перепроектирования.

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


      Не совсем так: мы используем SQL, от него никто не отказывается, но некий общий диалект (м.б. стандарт SQL-92, SQL-99...), который гарантированно поддерживается всеми реляционными СУБД. И этот диалект и считается интерфейсом DAL для доступа к реляционным данным.

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


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


      1. lair
        31.08.2015 18:05
        +2

        Использование «общего диалекта» приводит к тому, что на каждой СУБД работает неэффективный код. Не все это могут себе позволить.


        1. vmuravlev
          31.08.2015 18:16

          Ну, начнем с того, что DAL и подходит не всем :) Его сфера применения — это большое предприятие («кровавый enterprise» :))

          Использование «общего диалекта» приводит к тому, что на каждой СУБД работает неэффективный код. Не все это могут себе позволить.


          На мой взгляд, сформулировано чересчур категорично :) Точнее было бы, как мне кажется, сказать «иногда может привести к тому, что на каких-то СУБД будет работать неэффективный код».

          Конечно, такие ситуации будут встречаться, от качелей «универсальность VS эффективность» никуда не деться. Я думаю, что в таких случаях надо будет предусмотреть при организации DAL какие-то закладки, позволяющие выполнить нативный запрос. Но появление таких закладок должно быть исключением из правил и должно строго контролироваться на организационном уровне.


          1. lair
            31.08.2015 18:18

            Его сфера применения — это большое предприятие («кровавый enterprise» :))

            В кровавом энтерпрайзе вероятность смены БД оочень невысока. Они как посмотрят на стоимость миграции — и заодно проверки совместимости всех связанных систем — так и бросят эту идею. Плавали, ели, спасибо, нет.

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


            1. vmuravlev
              31.08.2015 18:27

              Плавали, ели, спасибо, нет.

              Если не сложно — можно подробнее про «плавали, ели»??


              1. lair
                31.08.2015 18:29

                Я работал с более чем одним крупным заказчиком (госучереждения, российский банк), каждый из которых на любые предложения сменить на существующей системе базу данных сразу отвечал «нет».


                1. vmuravlev
                  31.08.2015 18:35

                  А исходя из каких соображений крупному заказчику предлагали сменить СУБД для существующих систем?

                  Я работал в крупном российском банке, который сменил СУБД. На большом кол-ве существующих систем.


                  1. lair
                    31.08.2015 18:38

                    А исходя из каких соображений крупному заказчику предлагали сменить СУБД для существующих систем?

                    Разные варианты. Лицензирование, совместимость, производительность, функциональность.

                    Единственный аргумент, который на моей памяти работал — это сертификация.


                    1. vmuravlev
                      31.08.2015 18:49

                      То есть, не то чтобы «спасибо, нет», но все-таки «иногда да» ;)


                      1. lair
                        31.08.2015 18:50

                        Это по разряду «спасибо, нет… какая проверка?!»

                        Ну и я, в общем-то не зря написал «вероятность невысока», а не «смена невозможна».


  1. gandjustas
    02.09.2015 12:31
    +1

    В Java описанное довольно актуально — в качестве DAL выступает Hibernate. Его Criteria API и HQL еле-еле покрывают SQL-92, а вызовы хранимок в разных базах с точки зрения кода выглядят почти одинаково. Поэтому переход на другую РСУБД может оказаться не таким сложным делом. Особенно когда цена вопроса — отказ от лицензий Oracle.

    Причем вокруг Hibernate довольно легко построить свои обертки, которые не сильно снижают эффективность, поэтому во всех программах на Java ест ярко выраженный DAL.

    В случае .NET\C# картина совершенно иная. Там есть Linq, который сам по себе слой абстракции над запросами базы. Вот только уровень поддержки Linq разных провайдеров разный, поэтому используя Linq легко написать код, который будет работать только с MS SQL. С другой стороны Linq настолько мощен, что его нельзя абстрагировать в своем DAL без потери функциональности. Поэтому обычно все забивают на DAL, затачивают программу под конкретный движок СУБД, выжимая максимум.
    Получается быстрее в разработке и более эффективный код, но при этом сменить БД — проблема.

    На практике в любом серьезном проекте программа все равно неявно затачивается под конкретную СУБД и смена СУБД это далеко не только смена строки подключения. У меня есть прекрасный пример, когда смена MS SQL на Mongo увеличила объем кода приложения почти в 2 раза. Это при том, что архитектор утверждал, что Mongo идеально подходит для этого приложения. А в случае «кровавого ынтерпрайза», где много данных и в каждый запрос добавляется нетривиальный предикат проверки прав, подобный переход сделать еще сложнее.


    1. vmuravlev
      02.09.2015 15:13

      Linq настолько мощен, что его нельзя абстрагировать в своем DAL без потери функциональности.

      Вопрос может быть наивный (с .NET знаком весьма поверхностно, живу в Java мире):
      А разве нельзя накрыть эту мощную функциональность какими-нибудь репозиториями и, тем самым, последовать дао верного пути DAL? :)

      смена MS SQL на Mongo увеличила объем кода приложения почти в 2 раза

      Это как раз переход от одного класса данных к другому. Естественно, без переписывания никак.

      На практике в любом серьезном проекте программа все равно неявно затачивается под конкретную СУБД и смена СУБД это далеко не только смена строки подключения

      Здесь вопрос в том, что еще помимо строки подключения нужно исправить. При отсутствии DAL — это разбросанные по всему коду специфические SQL конструкции, при наличии DAL — все эти конструкции могут быть заключены в ограниченном наборе классов с выставленным API. Цена перехода для второго случая, как я думаю, существенно ниже.

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

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

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


      1. lair
        02.09.2015 15:19

        А разве нельзя накрыть эту мощную функциональность какими-нибудь репозиториями и, тем самым, последовать дао верного пути DAL?

        Во-первых, любой LINQ-провайдер — это уже DAL, так что формально задача выполнена. А во-вторых, если вы поверх этого будете строить еще один слой абстракции… ну да, можно. Но зачем?


        1. vmuravlev
          02.09.2015 16:52

          еще один слой абстракции… ну да, можно. Но зачем?

          Во-первых, для экранирования использования LINQ конструкций, специфичных для провайдеров.
          Во-вторых, для улучшения структуры и читаемости кода. Мне кажется, что любой запрос (неважно, SQL, HQL, LINQ) сложнее select с 1-2 условиями должен быть перенесен в метод репозитория с четким и ясным названием. Не 10 строк WHERE… AND… NOT EXISTS… BETWEEN и т.п., а что-то типа findAllUncompleteOrders. (Отец Эванс шлет нам горячий DDD привет! :))


          1. lair
            02.09.2015 17:03

            Уже неоднократно обсуждено, причем здесь же на хабре — при работе с LINQ запросы можно компоновать без применения репозитория. Например:

            for (var order = source.Orders.Uncomplete().ForPriorityCustomers())
            {
            ...
            }
            


      1. gandjustas
        02.09.2015 19:26

        А разве нельзя накрыть эту мощную функциональность какими-нибудь репозиториями и, тем самым, последовать дао верного пути DAL? :)

        Проблема в том, что любой самописный DAL значительно уменьшит мощность Linq. МС оценивает разработку Linq-провайдера в 2 человеко-года. Ни один ынтерпрайзный проект такие затраты нести не будет ради DAL. С другой стороны любой ORM с Linq делает ровно тоже самое, что описанный вами DAL.

        Это как раз переход от одного класса данных к другому. Естественно, без переписывания никак

        А изначально утверждалось обратное. Причем именно автором DAL.

        При отсутствии DAL — это разбросанные по всему коду специфические SQL конструкции, при наличии DAL — все эти конструкции могут быть заключены в ограниченном наборе классов с выставленным API.

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

        Суть любой абстракции для доступа к данным — генерация запросов. Для РСУБД запрос тем лучше (быстрее, тратит меньше ресурсов), чем он точнее — по максимуму определены все предикаты, написаны все джоины, указаны только нужные поля в проекции, указана сортировка и выборка по страницам.
        Часть сведений для построения запроса есть только в верхних слоях приложения (presentation layer), например проекция, сортировка и постраничное разбиение. Можно все передавать параметрами, но набор параметров пухнет с нереальной скоростью.

        В итоге идеальный DAL это не просто наборы методов с 1-2 параметрами, которые возвращают коллекции объектов. Идеальный DAL это метод Fetch, который принимает некоторый объект, содержащий все параметры — проекции, сортировки, джоины итд (query object). То есть ровно то, что делает ORM. При этом query object собирается не в одном месте, а постепенно в него добавляются параметры на всех слоях.

        Но тут всегда возникают database specific вещи: типы не совпадают, в одной базе можно написать x is null, а в другой нет, в одной базе есть функции, а в другой нет итд. То есть мелкие особенности попадают в логику приложения.

        И DAL тут не поможет, потому что если попытаться отказаться от query objeсt и все параметры передавать в методы как обычные параметры, то очень быстро наступает ад для поддержки.

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

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

        Тогда я не знаю что вы называете энтерпрайзом.
        Если вы просто называете так «ит-зоопарк», то никакого отношения к DAL он не имеет. Разработчик всегда работает с одной базой, которая заложена в архитектуру и под нее покупаются лицензии.
        Если энтерпразом вы называете большое количество существующей инфраструктуры, то тоже к DAL не имеет отношения. Все равно у вас основная база одна и ваше приложение нужно чтобы эту базу наполнять.
        Я бы называл энтерпрайзом задачи, где требуется учитывать структуру организации в логике приложения. Это неизменно ведет нас к запросам, которые как-то обрабатывают разрешения.

        Инкапсулировать такую логику нельзя. Потому что проверка разрешений не в самом запросе — адские тормоза и не работает уже при 5000 строк. Поэтому разработчики энтерпрайз систем вынуждены включать разграничения доступа в логику работы с базой. А это, с учетом проблем описанных выше, приводит к бесполезности DAL.

        ЗЫ. Тем не менее, когда средства генерации запросов очень слабые, как Hibernate в Java, то сделать DAL вокруг него не представляет проблем.


        1. vmuravlev
          02.09.2015 21:05

          Аминь.