Перевод статьи «Database versioning best practices», опубликованной на сайте enterprisecraftsmanship.com.
Отслеживание изменений базы данных вашего приложения является не легкой задачей. Как правило, схемы баз данных не совпадают в различных средах, данные в одной БД могут не иметь некоторых важных частей данных. Такие обстоятельства могут быть неприятными, особенно если возникают в production.
Ситуация становится еще хуже, если вы разработчик распространяемого ПО. В этом случае, каждый ваш клиент имеет собственный экземпляр БД, структура которого может отличаться от других. В таких проектах, отслеживание изменений БД клиентов может стать кошмаром.
Давайте рассмотрим лучшие подходы к управлению версиями баз данных.
Когда вы работаете над проектом в одиночку, который еще не выпущен в production, то не возникает таких проблем, как проблема управления версиями базы данных. Вы изменяете схему данных так, как вы хотите и это всегда работает.
Проблемы возникают, когда ваша программа начинает работать в production или новый участник команды присоединяется к работе над базой данных, связанной с частью вашего проекта. Как только у вас имеется более одного экземпляра базы данных, начинается рассинхронизация. Даже с одним экземпляром, требуется значительное количество времени, чтобы синхронизировать изменения, когда более чем один разработчик работает с ней.
Выглядит знакомо? Бьюсь об заклад у вас бывали такие ситуации, более чем единожды. У меня, кончено, бывали.
К счастью мы не одиноки. Есть множество материалов, написанных на эту тему. А также ПО, которое позволяет решать эту проблему. Я рекомендую эту книгу, если вы хотите изучить тему глубже. Это исчерпывающее руководство о том, как развивать БД совместно с кодом, который использует ее.
Хорошо, так что же это за лучшие практики для версионирования баз данных?
Best practice #1: мы должны относиться к базе данных приложения и справочным данных, как к обычному коду. Это значит, что мы должны хранить и схему, и справочные данные в системе управления версиями.
Обратите внимание, что это правило включает в себя не только схему базы данных, но также справочные данные. Справочные данные – это данные, которые обязательны для запуска приложения. Например, если у вас есть словарь всех возможных типов клиентов, на которых строится ваше приложение, вы должны хранить его в системе управления версиями.
Best practice #2: мы должны хранить все изменения в схеме базы данных и справочных данных в явном виде. Это означает, что для каждой модификации мы должны создать отдельный сценарий SQL с изменениями. Если модификация влияет как на схему, так и на справочные данные, они должны быть отражены в одном сценарии.
Следование этому правилу, является важной частью построения успешной системы управления версиями базы данных. У многих проектов хранятся схемы базы данных в системе управления версиями, но часто это просто снимок последней версии базы данных, вот и все. Все изменения в ней отслеживаются самой системой управления версиями, они не хранятся в явном виде. Кроме того, часто не отслеживаются все изменения в справочных данных.
Такие инструменты как Visual Studio подчеркивают и призывают программистов использовать автоматически сгенерированные скрипты для обновления схемы данных проекта базы данных. Это может хорошо работать в небольших проектах, но в больших проектах, отслеживание изменений в базе данных с использованием автоматически сгенерированных сценариев становится бременем. Мы будем говорить о проекте базы данных в Visual Studio и других доступных инструментах в следующем посте.
Best practice #3: каждый файл SQL скрипта должен быть неизменным после развертывания в production или промежуточную среды.
Смысл сохранения изменений в отдельных файлах состоит в том, что мы можем контролировать (отслеживать) каждый из них. Когда мы изменяем существующие сценарии SQL, мы теряем все преимущества работы с лучшими практиками версионирования баз данных предоставленных нам. Сохраняйте файлы сценариев неизменными после их развертывания. Если вам нужно откатить изменения, которые уже совершены — создайте отдельный сценарий для этого.
Best practice #4: все изменения в схеме и справочных данных в базах данных должны быть применены через скрипты. Ни один из них может быть применен вручную.
Если мы изменяем базу данных в обход наших скриптов, вся идея версионирования базы данных становится бесполезной, так что мы должны убедиться, что изменения сделаны только с помощью скриптов SQL, которые мы создаем.
Best practice #5: каждый разработчик в команде должен иметь свой экземпляр базы данных.
Часто, команды начинают с единой базы данных в среде разработки. Это хорошо работает в начале, но, когда база данных становиться достаточно большой, одновременная ее модификации становится все труднее и труднее, пока в некоторой точке не перестает работать у всех.
Часто программисты делают несовместимые изменения, так что это хорошая идея, чтобы каждый программист имел отдельный экземпляр базы данных, воизбежании таких коллизий. Если разработчики делают изменения какой-то части схемы БД одновременно, то такие конфликты могут быть разрешены с помощью системы управления версиями, как конфликты в C # / Java и т.д.
Кроме того, если у вас есть несколько веток вашей кодовой базы, вы также можете создать отдельный экземпляр базы данных для каждой из них, в зависимости от того, какие различия БД в этих ветках имеются.
Best practice #6: версии базы данных должны храниться в самой базе данных. Я, как правило, создаю отдельную таблицу с названием «Settings» и храню версию там. Не используйте сложные обозначения типа «x.y.z» для номеров версий, просто используйте целое число.
Так какие же преимущества нам дают лучшие подходы к версионированию баз данных?
Первый и самый главный плюс состоит в том, что, используя этот подход, мы больше не имеем проблем с несоответствием схемы базы данных. Автоматическое обновление до последней версии решает их полностью, конечно, если мы в полной мере придерживаться правил, описанных выше.
Это особенно полезно, когда у вас нет единой production базы данных, но каждый клиент имеет свой собственный экземпляр базы данных. Управление версией БД в таких условиях может стать адом, если вы не использовать правильные техники управления версиями.
Еще одним достоинством использования лучших практик, является сильная связность изменений в базе данных. Это означает, что каждая известный модификация в схеме и справочных данных отражается в одном месте, а не разбросана по приложению.
Сценарии обновления SQL наделены сильной связностью, в том смысле, что они содержат все необходимы изменения для БД, так что легко понять, что изменения были сделаны в базе данных для того, чтобы разблокировать конкретный функционал. Сохранение схемы и изменений данных, связанных друг с другом в одном файле также сильно помогает.
Описанный в этом посте подход применим, даже если вы не следовали ему с самого начала. Чтобы использовать это на практике нужно просто создать первоначальный сценарий схемы базы данных, который вы имеет на данный момент в production и можете постепенно начать изменять его с этого момента. Текущая версия, должна стать версией #1, с которой вы можете двигаться дальше, используя подходы, которые мы обсуждали выше.
Отслеживание изменений базы данных вашего приложения является не легкой задачей. Как правило, схемы баз данных не совпадают в различных средах, данные в одной БД могут не иметь некоторых важных частей данных. Такие обстоятельства могут быть неприятными, особенно если возникают в production.
Ситуация становится еще хуже, если вы разработчик распространяемого ПО. В этом случае, каждый ваш клиент имеет собственный экземпляр БД, структура которого может отличаться от других. В таких проектах, отслеживание изменений БД клиентов может стать кошмаром.
Давайте рассмотрим лучшие подходы к управлению версиями баз данных.
Управление версиями баз данных: проблема
Когда вы работаете над проектом в одиночку, который еще не выпущен в production, то не возникает таких проблем, как проблема управления версиями базы данных. Вы изменяете схему данных так, как вы хотите и это всегда работает.
Проблемы возникают, когда ваша программа начинает работать в production или новый участник команды присоединяется к работе над базой данных, связанной с частью вашего проекта. Как только у вас имеется более одного экземпляра базы данных, начинается рассинхронизация. Даже с одним экземпляром, требуется значительное количество времени, чтобы синхронизировать изменения, когда более чем один разработчик работает с ней.
Выглядит знакомо? Бьюсь об заклад у вас бывали такие ситуации, более чем единожды. У меня, кончено, бывали.
Лучшие подходы к к управлению версиями баз данных
К счастью мы не одиноки. Есть множество материалов, написанных на эту тему. А также ПО, которое позволяет решать эту проблему. Я рекомендую эту книгу, если вы хотите изучить тему глубже. Это исчерпывающее руководство о том, как развивать БД совместно с кодом, который использует ее.
Хорошо, так что же это за лучшие практики для версионирования баз данных?
Best practice #1: мы должны относиться к базе данных приложения и справочным данных, как к обычному коду. Это значит, что мы должны хранить и схему, и справочные данные в системе управления версиями.
Обратите внимание, что это правило включает в себя не только схему базы данных, но также справочные данные. Справочные данные – это данные, которые обязательны для запуска приложения. Например, если у вас есть словарь всех возможных типов клиентов, на которых строится ваше приложение, вы должны хранить его в системе управления версиями.
Best practice #2: мы должны хранить все изменения в схеме базы данных и справочных данных в явном виде. Это означает, что для каждой модификации мы должны создать отдельный сценарий SQL с изменениями. Если модификация влияет как на схему, так и на справочные данные, они должны быть отражены в одном сценарии.
Следование этому правилу, является важной частью построения успешной системы управления версиями базы данных. У многих проектов хранятся схемы базы данных в системе управления версиями, но часто это просто снимок последней версии базы данных, вот и все. Все изменения в ней отслеживаются самой системой управления версиями, они не хранятся в явном виде. Кроме того, часто не отслеживаются все изменения в справочных данных.
Такие инструменты как Visual Studio подчеркивают и призывают программистов использовать автоматически сгенерированные скрипты для обновления схемы данных проекта базы данных. Это может хорошо работать в небольших проектах, но в больших проектах, отслеживание изменений в базе данных с использованием автоматически сгенерированных сценариев становится бременем. Мы будем говорить о проекте базы данных в Visual Studio и других доступных инструментах в следующем посте.
Best practice #3: каждый файл SQL скрипта должен быть неизменным после развертывания в production или промежуточную среды.
Смысл сохранения изменений в отдельных файлах состоит в том, что мы можем контролировать (отслеживать) каждый из них. Когда мы изменяем существующие сценарии SQL, мы теряем все преимущества работы с лучшими практиками версионирования баз данных предоставленных нам. Сохраняйте файлы сценариев неизменными после их развертывания. Если вам нужно откатить изменения, которые уже совершены — создайте отдельный сценарий для этого.
Best practice #4: все изменения в схеме и справочных данных в базах данных должны быть применены через скрипты. Ни один из них может быть применен вручную.
Если мы изменяем базу данных в обход наших скриптов, вся идея версионирования базы данных становится бесполезной, так что мы должны убедиться, что изменения сделаны только с помощью скриптов SQL, которые мы создаем.
Best practice #5: каждый разработчик в команде должен иметь свой экземпляр базы данных.
Часто, команды начинают с единой базы данных в среде разработки. Это хорошо работает в начале, но, когда база данных становиться достаточно большой, одновременная ее модификации становится все труднее и труднее, пока в некоторой точке не перестает работать у всех.
Часто программисты делают несовместимые изменения, так что это хорошая идея, чтобы каждый программист имел отдельный экземпляр базы данных, воизбежании таких коллизий. Если разработчики делают изменения какой-то части схемы БД одновременно, то такие конфликты могут быть разрешены с помощью системы управления версиями, как конфликты в C # / Java и т.д.
Кроме того, если у вас есть несколько веток вашей кодовой базы, вы также можете создать отдельный экземпляр базы данных для каждой из них, в зависимости от того, какие различия БД в этих ветках имеются.
Best practice #6: версии базы данных должны храниться в самой базе данных. Я, как правило, создаю отдельную таблицу с названием «Settings» и храню версию там. Не используйте сложные обозначения типа «x.y.z» для номеров версий, просто используйте целое число.
Каковы преимущества такого подхода?
Так какие же преимущества нам дают лучшие подходы к версионированию баз данных?
Первый и самый главный плюс состоит в том, что, используя этот подход, мы больше не имеем проблем с несоответствием схемы базы данных. Автоматическое обновление до последней версии решает их полностью, конечно, если мы в полной мере придерживаться правил, описанных выше.
Это особенно полезно, когда у вас нет единой production базы данных, но каждый клиент имеет свой собственный экземпляр базы данных. Управление версией БД в таких условиях может стать адом, если вы не использовать правильные техники управления версиями.
Еще одним достоинством использования лучших практик, является сильная связность изменений в базе данных. Это означает, что каждая известный модификация в схеме и справочных данных отражается в одном месте, а не разбросана по приложению.
Сценарии обновления SQL наделены сильной связностью, в том смысле, что они содержат все необходимы изменения для БД, так что легко понять, что изменения были сделаны в базе данных для того, чтобы разблокировать конкретный функционал. Сохранение схемы и изменений данных, связанных друг с другом в одном файле также сильно помогает.
Описанный в этом посте подход применим, даже если вы не следовали ему с самого начала. Чтобы использовать это на практике нужно просто создать первоначальный сценарий схемы базы данных, который вы имеет на данный момент в production и можете постепенно начать изменять его с этого момента. Текущая версия, должна стать версией #1, с которой вы можете двигаться дальше, используя подходы, которые мы обсуждали выше.