Реляційні бази даних та ітеративна розробка


19

У багатьох підходах до розробки програмного забезпечення, таких як гнучкі методології, дизайн, керований доменом та об'єктно-орієнтований аналіз та дизайн, нам пропонується застосувати один ітеративний підхід до розробки.

Таким чином, ми не повинні робити нашу доменну модель правильно в перший раз, коли ми починаємо працювати над проектом. Натомість, з часом ми перетворюємо модель, оскільки з часом ми глибше розуміємо проблемну область.

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

Сенс у тому, що нам може знадобитися змінити модель після розгортання програмного забезпечення. Якщо це трапилося, у нас є проблема: у виробничій базі даних є важливі дані користувачів, які вже встановлені у форматі для старої моделі .

Оновлення коду може бути важким завданням, якщо код не розроблений належним чином і якщо система велика. Але це можна зробити з часом, у нас є такі інструменти, як Git, які допомагають нам це робити, не пошкоджуючи готову до виробництва версію.

З іншого боку, якщо модель змінюється, якщо властивості класів зникають чи що завгодно, база даних також повинна змінюватися. Але у нас є проблема: там уже є дані, які неможливо втратити, що вже сформовано для старої моделі.

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

Я вже використовував один підхід для кодування спеціального класу, який відображає старі таблиці баз даних на нові. Тож ці класи вибирають дані у старому форматі, перетворюють їх у формат, використаний новою моделлю, та зберігають у нових таблицях.

Цей підхід, здається, не найкращий. Моє запитання тут: чи існують відомі та рекомендовані підходи для узгодження ітеративного розвитку з реляційними базами даних?


6
До речі, я не думаю, що це стосується зокрема реляційних баз даних. У мене є аналогічна проблема з проектом, над яким я працюю, але ми маємо це зі схемою для наших струн JSON, які представляють дуже нереляційні об'єкти. Це, ймовірно, впливає на всі форми стійкості однаково.
Ixrec

1
Ви змінюєте схему бази даних таким чином, щоб вона не втрачала даних, en.wikipedia.org/wiki/Schema_migration .
RemcoGerlich

1
Я впевнений, що ця тема десь широко обговорювалася раніше, я просто не можу її знайти у програмістів. Але побачити тут martinfowler.com/articles/evodb.html або тут stackoverflow.com/questions/334059 / ...
Doc Brown

1
"Крім цього, навіть якщо ми намагатимемося отримати вдосконалену модель вперед, що, я вже переконаний, дуже важко, вимоги можуть змінитися". Я хотів би додати, що ви навіть не повинні намагатися отримати (близьку до ідеальної) модель вперед. Це може прив’язати ваше мислення до одного типу рішень, а не залишати параметри відкритими.
Бент

Відповіді:


15

Це не повинні бути спеціальні класи, але так, вам потрібно щось, що займе базу даних у попередньому форматі та перетворить її у поточну.

Вся справа в тому, що вам потрібно розробити процес написання та тестування цих сценаріїв і дисципліну, щоб ніколи не торкатися баз даних тестування та виготовлення вручну, а завжди за сценаріями міграції.

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

І переконайтеся, що ви коли-небудь змінюєте будь-яке середовище спільної розробки, тестування та контролю якості, застосовуючи сценарії та повертаючись до попередньої версії, якщо вони не працюють, тож ви можете бути впевнені, що вони працюватимуть за призначенням, коли ви їх розблокуєте на виробництві .

Нова установка виконується просто за допомогою застосування всіх сценаріїв. Через деякий час у вас може з’явитися сотні, і ви подумаєте, що це дуже неефективно, але не потрапляйте в пастку, намагаючись оптимізувати його. Установка - це разове заняття, а її надійні козирі роблять її швидкою.

@Doc Браун вже пов’язав Мартіна Фаулера: Еволюційний дизайн баз даних та /programming/334059/agile-development-and-database-changes , і я додав би Алекса Пападімуліса: Зміни бази даних виконано праворуч , що коротше і має кілька прикладів.

Як гідний приклад інструментальної реалізації такого процесу, я пропоную Alembic . Він заснований на основі Python SQLAlchemy , але ви можете використовувати його з іншими мовами та структурами, якщо вони не мають власної підтримки міграції. На сторінці Вікіпедії на схемі міграції перелічено більше таких інструментів .


1
@Tibo ви будуєте схему з нуля, запускаючи ту саму послідовність сценаріїв. Ось як ви керуєте проблемою. Враховуючи, що в якості стандарту ви можете потрапити з будь-якого примірника бази даних - включаючи таку, яка ще не існує - до поточної схеми і впевнені, що її однакова. Немає необхідності мати два способи згідно з вашим прикладом. (Принаймні, не дано послідовної базової лінії - перший крок - це встановити базову лінію, і як тільки ви дістанетесь до цієї базової лінії, проблема відходить.)
Мерф

1
Великі пальці до статті Алекса; він може бути не коротшим, але він робить набагато більш орієнтованим на практику та захоплюючим читанням.
Мерфі

1
Ми магазин Agile і ми працюємо на 100% безперервного обслуговування, і обидва вони застосовуються і до БД. Ми мігруємо виробничу схему в середньому один раз на день, і я би другий усе, що сказав Ян. Ще одне, що ми робимо, що було неоціненним, - це те, що ми називаємо тестуванням міграції. Це працює як частина нашого процесу складання та розгортання. Він робить знімок схеми з виробництва, застосовує будь-які очікувані міграції з головного на нього, а потім запускає одиничні тести з поточно розгорнутого виробничого коду проти цієї схеми. Мета - перевірити, що застосування міграцій не порушить працюючу систему.
Гордон Вріглі

1

Як не дивно, це проблема, яка стоїть перед моєю нинішньою командою з розвитку. Питання містить кілька підзапитів, тому вони будуть вирішені самостійно.

Перш за все, чи реляційна база даних занадто сильно обмежує модель даних, що робить зміни дуже важкими?

Звичайно , але не обов'язково з наведених причин. На жаль, універсальність систем управління реляційними базами даних також призводить до їх падіння. RDBMS спочатку був розроблений, щоб запропонувати відносно просту платформу зберігання даних, яка б приймала великі набори даних і зменшувала їх до відносно невеликого розміру. Це було зроблено за рахунок складності в моделі даних та необхідної обчислювальної потужності. Із збільшенням складності бази даних зберігаються процедури, перегляди, функції та тригери, щоб допомогти адміністраторам баз даних вирішувати складність послідовно та масштабовано.

На жаль, модель реляційних баз даних не є об'єктно-орієнтованою і, природно, не відображається на реальних сутностях, як це має бути модель даних. Це призводить нас до необхідності таких інструментів посередників, як об'єктно-реляційні картографи тощо. На жаль, хоча ці засоби очевидно мають місце в сучасному світі розвитку, їх використання є орієнтованим лише на симптом проблеми складності реляційних даних, а не на основну причину, яка є невідповідністю моделі даних реального світу.

Це призводить до другої частини питання, яка насправді була більшою припущенням, але слід розглядати як питання: чи ми повинні вперше зробити нашу доменну модель правильно?

Так, певною мірою. Як зазначалося в питанні, рідко вдається повністю зрозуміти проблему, коли ми починаємо процес проектування. Однак різниця між абсолютно невірною моделлю даних, на відміну від тієї, яку можна змінити, коли ми отримуємо більш широке розуміння домену, - це модель, яка послідовно відображає реальний світ. Це означає, що ми повинні докласти максимум зусиль, щоб створити початкову модель даних, яка відповідає нашому розумінню проблеми з точки зору її реальних сутностей. Якщо ми почнемо нормалізуватися на неправильних об'єктах, модель даних буде помилятися двома способами, і відновлення буде важким.

Багато в чому перехід до рішень бази даних "Без SQL" є результатом проблем невідповідності моделі даних. Використання об'єктно-орієнтованого ніякого підходу SQL не змушує думати більше про відображення між нашими об'єктами в коді та об'єктами в реальному світі, і коли ми стикаємося з невідповідністю, це часто само собою зрозуміло, оскільки це неможливо реалізувати в нашому база даних. Це призводить до кращого загального дизайну.

Це призводить до остаточного питання: чи модель реляційних даних не відповідає гнучкому підходу?

Ні, але більше навичок не потрібно. Тоді як у світі No-SQL тривіально додати поле або перетворити властивість у масив, це зовсім не банально робити це у реляційному світі. Потрібно, як мінімум, того, хто здатний зрозуміти як реляційну модель даних, так і реальну сутність, яку вони представляють. Ця людина - це людина, яка сприятиме оновленню реляційної моделі в міру зміни розуміння моделі реального світу. Срібної кулі для вирішення цієї проблеми немає.


1
Я дуже сподіваюся, що ви завеликої проблеми створили нове поле в таблиці RDBMS, щоб зробити заяву більш драматичним. Таблиця бази даних повинна бути дуже спеціальною (або новий тип поля повинен бути чимось винятковим), щоб дійсно створити проблему, щоб додати одне поле.
Олексій Зімарьов

Так, але це ніколи не одне поле ...
Майер

1
Я б сказав, частіше, це лише одне поле. Драматичні зміни схеми не так часто. Я не прихильник використання RDBMSes з OO дизайном через невідповідність імпедансу. Однак додавання нових типів (таблиць) та властивостей (стовпців) порівняно просто в обох світах, хоча в NoSQL це справді трохи простіше. Але складні зміни - це біль в обох випадках. Ще гірше стає в системі, що базується на подіях із знімками, навпаки, наскільки приємним є досвід розвитку такої системи.
Олексій Зімарьов

Я бачу, що реляційні бази даних часто використовуються як "універсальний молоток" для вирішення потреб у сховищі даних - коли насправді є дуже конкретні причини їх використання. У ретельно продуманій системі рідко доводиться турбуватися про проблеми, про які я писав у своїй відповіді - я звертаюся до більш загальної аудиторії, яка, можливо, не має досвіду, щоб прийти до відповідного дизайну системи наперед.
theMayer

Не існує розбіжностей між реляційною моделлю, і вона зазвичай відображається в реальному світі так само, як і будь-яка інша модель. Деякі операції будуть простішими з одним видом, а інші з іншими. Проблема полягає в тому, що ви створюєте модель одного виду (об'єктно-орієнтована) і намагаєтесь реалізувати її за допомогою інструментів іншого виду (реляційних). Це не добре працює. Але реальний світ не є об'єктно-орієнтованим. Це просто так, і ти його моделюєш. І доводиться використовувати правильні інструменти для обраного типу моделі.
Ян Худек

-1

Головне - не переробляти так сильно, щоб ваша модель змінювалась поза всім розпізнаванням. Навіть при ітераційній розробці ви дійсно повинні будувати поверх існуючих речей, а не переробляти їх на частини.

Це дає вам 2 основні варіанти обробляти великі зміни, коли вони приходять: перший - створити рівень DB як API, використовувати збережені процедури, щоб вони могли бути змінені відповідно до клієнта без зміни основної схеми даних.

Інший спосіб - замінити таблиці невеликою міграцією даних. Коли потрібна велика зміна масштабу, ви створюєте нову схему та реалізуєте набір сценаріїв, щоб взяти старі дані та перемістити їх у новий формат. Для цього це витрачає час, тому ви більше покладаєтесь на більш дешеві методи зміни доступу до даних (наприклад, через SP) як перший вибір.

Отже: 1. постарайтеся продумати дизайн заздалегідь, щоб вам не потрібно щось змінювати.

  1. Покладайтеся на обгортки або API, тому зміни обмежені або можуть бути приховані всередині ізольованого компонента

  2. Знайдіть час для належного оновлення, якщо вам доведеться.

Ці кроки стосуються всього, а не лише баз даних.


Основну схему іноді потрібно змінити. Коли програма проходить тестування клієнтів, з'являються нові атрибути, про які ви ніколи не чули, атрибути, які ви вважали числами, виявляються рядками, відносини, які, як ви очікували, становлять 1: 1, виявляються такими, що не так і так далі. Ви не можете охоплювати такі речі за збереженими процедурами (до того ж, що зберігаються процедури є частиною проблеми, оскільки, як і інші речі в базі даних, вони не живуть у контролі версій).
Ян Худек

@JanHudec з тих пір, коли SP не живуть у контролі версій? Ви можете охоплювати такі речі, ви змінюєте API SP на те, щоб взяти рядок і записати його в інше поле, обробляючи старі номери та нові рядки з невеликим кодом у вашому SP. Не найприємніше, але це може бути краще, ніж перейти на кожен клієнтський сайт, щоб перенести свої дані у новий формат рядків (є кращі приклади, але ви розумієте). Якщо зміна виявиться великою, вам доведеться перейти, але принаймні з API API у вас є й інші, дешевші, варіанти.
gbjbaanb

Вам потрібно зайти на кожен сайт клієнта, щоб встановити SP та додати нове поле. А коли ви там, можете також перемістити дані. ІП корисні тим, що вони дозволяють створювати зворотний сумісний інтерфейс, якщо у вас є кілька додатків, які мають доступ до бази даних, тому вам не потрібно одночасно оновлювати їх. Але вони не зберігають жодних кроків, коли схему потрібно змінити через зміни вимог.
Ян Худек
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.