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

9

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

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

Редактировать: От этого так много отвращения, мне интересно, сколько проектов заканчивают тем, что не добавили функцию, которая требует радикального изменения базы данных, или используются ненормализованные подходы, такие как добавление поля DepartmentID2 вместо новой таблицы. Потребность в нескольких отделах для сотрудника является распространенной проблемой домена. Я просто не заметил многих схем баз данных, которые изобилуют отношениями «многие ко многим».

JeffO
источник
1
+1 Спасибо за вопрос. Я многому научился, читая ответы на мой оригинальный вопрос, и это тоже проницательная тема.
Джим

Ответы:

3

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

Вы можете прочитать больше о рефакторинге базы данных здесь .

Pramod
источник
Этот сайт - то, что вызвало вопрос в первую очередь;)
JeffO
14

Рефакторинг кода прост - вы просто меняете код и запускаете свои регрессионные тесты.

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

Страшные вещи.

Мэтью Флинн
источник
Тесты базы данных не должны быть другими. Все изменения требуют аудита и влияют на резервное копирование. Сколько данных вы собираетесь накопить, прежде чем признать эту необходимость? Если вы конвертировали данные, эта функция была бы еще более очевидной.
Джефф
8
+1 для @Mathew Flynn. Сколько данных вы собираетесь накопить, прежде чем признать эту необходимость? Миллионы рядов. Другая проблема заключается в том, что ВАШЕ приложение не единственное, что использует базу данных. База данных может иметь много приложений, работающих с ней, и вы можете даже не знать, что они существуют (например, дикие приложения «BI»). Изменения в схемах баз данных являются страшно.
Анджело
2
Иногда миллиарды строк
HLGEM
1
Если вы имеете дело с миллиардами строк, вы лучше знаете, как их перемещать
Джефф
3

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

0x4B1D
источник
1
Вы могли бы выдвинуть этот аргумент для отдельного случая или двух, но когда «биты» времени складываются слишком много?
Джефф
Исходя из моего собственного опыта, это на самом деле относится к подавляющему большинству проектов. Но я также думаю, что это приходит с опытом и очень субъективно :) Я был бы удивлен, если бы кто-то мог дать вам точный рецепт (отсюда и «тонкая грань»).
0x4B1D
@ Джефф О: Это не будет «бит». Требуется 10% или 20% затрат времени разработки на упрочнение, потому что система может пережить как первоначально предусмотренные сроки, так и вашу занятость.
Руонг
3

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

На практике я обычно не обнаруживал, что это правда, но я полагаю, что SQL ближе к тому, чем он должен быть, чтобы поддерживать многие ко многим, чем это было бы иначе.

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

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

ИМХО, это не понадобилось бы, если бы у нас был лучший язык, чем SQL, для определения реляционной алгебры. Если бы было возможно построить SQL-запрос по частям с помощью объектов, которым не нужна видимость каждой таблицы в запросе, этого бы не произошло. Такие вещи, как LINQ (для SQL или для сущностей), пытаются решить эту проблему, но это очень сложное решение и его сложно оптимизировать (и я был в группах пользователей DBA, где упоминается LINQ, и каждый раз поднимается коллективный стон). Я мечтаю о языке баз данных, который универсально поддерживается функциями реляционной алгебры первого класса ...

В то же время, да, вы можете рефакторинг от 1-ко-многим до многих-ко-многим, но это может быть много работы.

PSR
источник
Ты не собираешься превратить все отношения во многие ко многим?
Джефф
@ Джефф О - Не уверен, что понимаю ваш вопрос. Когда вы сомневаетесь, я моделирую «многие ко многим», чтобы избежать ошибок, упомянутых в различных ответах на ваш первоначальный вопрос. Я стал немного осторожнее после того, как поддержал базы данных, которые действительно делали почти все отношения многими ко многим, потому что в итоге они делали такие вещи, как создание представлений, которые делали отношения кажущимися «один ко многим» (что на практике они все были). Таким образом, у них было худшее из обоих миров. У меня никогда не было такого на моих собственных проектах, но это как предостерегающая история.
PSR
3

Я обычно объясняю это таким образом PHB - код - это стены и крыша, база данных - это основа.

Перемещение стен и изменение крыши может быть сделано. Для смены фундамента требуется много копать и перестраивать стены и крышу.

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

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

JQA
источник
1

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

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

Реализация «один ко многим» обходится не так много, как «многие ко многим», но рефакторинг базы данных и приложения для поддержки «многие ко многим» дорог и сопряжен с трудностями.

Джеймс Андерсон
источник
Я согласен, что есть много зрелых доменов (например, HR), где клиент не предвидит необходимость, но вы знаете, что это обязательно произойдет.
Джефф
0

Существует два способа взглянуть на дизайн программного обеспечения (и, возможно, многие другие): тактический или стратегический. У каждого есть свои преимущества и недостатки.

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

Я придерживаюсь своего принципа, который гласит: « Когда это возможно, стратегически разрабатывайте совместно используемые программные артефакты » - это может звучать так, как будто это противоречит принципу YAGNI, однако это мое мнение. Такой подход гарантирует меньше переделок за счет сложности и ресурсов.

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

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

Так что лучше предвидеть это с самого начала.

Без шансов
источник
Все лучше предвидеть с самого начала.
Джефф
0

Как сказал Мэтью выше, рефакторинг / изменение баз данных часто более сложны по сравнению с программным обеспечением, так как управление данными также необходимо принимать во внимание. Существуют методы, которые могут помочь, например, обеспечить наличие соответствующего набора модульных тестов базы данных, отделить клиентские приложения от базовой схемы с помощью «API БД» - sprocs / views и т. Д.

mbaylon
источник