Кращі підходи до керування версіями баз даних

Переклад статті «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, з якою ви можете рухатися далі, використовуючи підходи, які ми обговорювали вище.