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

19

Во многих подходах к разработке программного обеспечения, таких как гибкие методологии, доменно-ориентированное проектирование и объектно-ориентированный анализ и проектирование, нам предлагается использовать один итеративный подход к разработке.

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

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

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

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

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

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

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

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

user1620696
источник
6
Кстати, я не думаю, что это как-то связано с реляционными базами данных. У меня есть похожая проблема с проектом, над которым я работаю, но у нас есть его со схемой для наших строк JSON, которые представляют очень нереляционные объекты. Это, вероятно, влияет на все формы постоянства одинаково.
Ixrec
1
Вы изменяете схему базы данных таким образом, чтобы не потерять данные, en.wikipedia.org/wiki/Schema_migration .
RemcoGerlich
1
Я уверен, что эта тема широко обсуждалась где-то раньше, просто не могу найти ее на программистов. Но смотрите здесь martinfowler.com/articles/evodb.html или здесь stackoverflow.com/questions/334059/…
Док Браун
1
«Помимо этого, даже если мы попытаемся получить идеальную модель заранее, что, как я уже убежден, очень сложно, требования могут измениться». Я хотел бы добавить, что вы не должны даже пытаться получить (близкую к идеальной) модель заранее. Это может связать ваше мышление с одним типом решений вместо того, чтобы держать ваши варианты открытыми.
согнут

Ответы:

15

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

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

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

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

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

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

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

Ян Худек
источник
1
@ Тибо вы строите схему с нуля, выполняя ту же последовательность сценариев. Вот как вы справляетесь с проблемой. Учитывая, что в качестве стандарта вы можете получить из любого экземпляра базы данных - включая тот, который еще не существует, - к текущей схеме и иметь уверенность, что она такая же. Там нет необходимости иметь два пути в соответствии с вашим примером. (По крайней мере, с учетом непротиворечивой базовой линии - первый шаг - установить базовую линию, и как только вы доберетесь до этой базовой линии, проблема исчезнет.)
Murph
1
Недурно для статьи Алекса; это не может быть короче, но это делает намного более ориентированное на практику и интересное чтение.
Мерфи
1
Мы магазин Agile, и у нас 100% бесперебойная работа, и оба они применимы и к БД. Мы переносим производственную схему в среднем один раз в день, и я повторю все, что сказал Ян. Еще одна важная вещь, которую мы делаем, - это то, что мы называем миграционным тестированием, которое выполняется как часть нашего процесса сборки и развертывания. Он снимает моментальный снимок схемы с производства, применяет к нему все ожидающие миграции от мастера, а затем запускает модульные тесты из развернутого в настоящее время производственного кода для этой схемы. Цель состоит в том, чтобы проверить, что применение миграций не сломает работающую систему.
Гордон Ригли
1

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

Прежде всего, не слишком ли сильно ограничивает реляционную базу данных модель данных, делая изменения очень трудными?

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

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

Это приводит ко второй части вопроса, которая на самом деле была скорее предположением, но должна рассматриваться как вопрос: должны ли мы сделать нашу модель предметной области правильно с первого раза?

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

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

Это приводит к последнему вопросу: не противоречит ли реляционная модель данных гибкому подходу?

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

theMayer
источник
1
Я действительно надеюсь, что вы не заметили проблему создания нового поля в таблице RDBMS, чтобы сделать это заявление более драматичным. Таблица базы данных должна быть очень особенной (или новый тип поля должен быть чем-то исключительным), чтобы действительно создать проблему для добавления одного поля.
Алексей Зимарев
Да, но это никогда не только одно поле ...
theMayer
1
Я бы сказал, чаще всего это только одно поле. Драматические изменения схемы не так часто. Я не фанат использования СУБД с ОО-дизайном из-за несоответствия импеданса. Тем не менее, добавление новых типов (таблиц) и свойств (столбцов) относительно легко в обоих мирах, хотя в NoSQL это действительно немного проще. Но сложные изменения являются болью в обоих случаях. Еще хуже становится в системе с событиями со снимками, в отличие от того, насколько приятен опыт разработки для такой системы.
Алексей Зимарев
Я вижу, что реляционные базы данных часто используются в качестве «универсального молотка» для решения задач хранения данных - хотя на самом деле есть очень конкретные причины для их использования. В тщательно продуманной системе редко приходится беспокоиться о проблемах, о которых я писал в своем ответе - я обращаюсь к более широкой аудитории, у которой может не быть опыта, чтобы прийти к соответствующему проектированию системы заранее.
TheMayer
Нет никаких расхождений между реляционной моделью, и она обычно сопоставляется с реальным миром так же, как и с любым другим типом модели. Некоторые операции будут проще с одним видом, а другие - с другим. Проблема в том, что вы создаете модель одного вида (объектно-ориентированную) и пытаетесь реализовать ее с помощью инструментов другого типа (реляционных). Это не работает хорошо. Но реальный мир не является объектно-ориентированным. Это просто, и вы моделируете это. И должны использовать правильные инструменты для выбранного типа модели.
Ян Худек
-1

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

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

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

Итак: 1. попробуйте подумать о дизайне, чтобы вам не пришлось ничего менять.

  1. Положитесь на оболочки или API-интерфейсы, поэтому изменения ограничены или могут быть скрыты внутри изолированного компонента

  2. Потратьте время, чтобы обновить должным образом, если вам нужно.

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

gbjbaanb
источник
Базовая схема иногда требует изменения. По мере того, как приложение начинает тестирование клиентов, появляются новые атрибуты, о которых вы никогда не слышали, атрибуты, которые вы считали числами, оказываются строками, отношения, которые вы ожидали равными 1: 1, оказываются не такими, как все, и так далее. Вы не можете охватить такого рода вещи за хранимыми процедурами (кроме того, хранимые процедуры являются частью проблемы, потому что, как и другие вещи в базе данных, они не живут в управлении версиями).
Ян Худек
@JanHudec с каких пор SP не живут в системе контроля версий? Вы можете охватить такие вещи, вы измените SP API, чтобы взять строку и записать ее в другое поле, обрабатывая старые числа и новые строки в небольшом количестве кода в вашем SP. Не самый хороший, но это может быть лучше, чем переходить на каждый сайт клиента, чтобы перенести свои данные в новый формат строки (есть лучшие примеры, но вы поняли идею). Если изменение окажется значительным, вам придется мигрировать, но по крайней мере с API БД у вас есть и другие, более дешевые варианты.
gbjbaanb
Вам все равно нужно перейти на сайт каждого клиента, чтобы установить SP и добавить новое поле. И когда вы там, вы можете перенести данные тоже. SP полезны тем, что они позволяют создавать обратно совместимый интерфейс, если у вас есть несколько приложений, обращающихся к базе данных, поэтому вам не нужно обновлять их все одновременно. Но они не сохраняют никаких шагов, когда схема должна измениться из-за меняющихся требований.
Ян Худек