Подтвердить что ты не робот

Рекомендации по переносу содержимого базы данных из одной очень плохой структуры в одну очень логичную?

TL; DR - лучший способ миграции большого количества данных между одной очень плохо структурированной базой данных (с большим количеством повторений столбцов, без взаимосвязи и дублирующихся данных), с другой высокоорганизованной и реляционной структурой? - Извините за долгое чтение!

Недавно я занялся очень сложной работой. Он переписывает всю сетевую ИТ-платформу компании. Боюсь, я не могу дать слишком много деталей, потому что мы не можем допустить, чтобы старый разработчик знал (у него есть метафорическое оружие против главы компании, в котором он единственный, кто знает, как делать критические вещи, такие как создание счетов, и требует все больше и больше денег).

Основная проблема заключается в том, что вся веб-платформа (используемая всем персоналом и всеми клиентами) была закодирована парнем, обладающим навыками меньше, чем любителем. Он состоит из ~ 300 отдельных файлов кода. Там нет библиотеки шаблонов - все это жестко закодировано в каждый файл. Нет логической структуры базы данных - она ​​практически была составлена, когда он шел. Нет никакой безопасности - это шокирует. Во всяком случае, мы будем переписывать всю эту платформу в течение 3-месячного периода.

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

Одним из примеров является адрес. В старой базе данных адреса используются примерно в 12 таблицах (из 44 всего...). В нашем случае у нас есть одна таблица addresses, которая будет перекрестно ссылаться на другие таблицы (например, address_id), чтобы сохранить чистоту. Основная проблема заключается в том, что примерно в половине его таблиц адреса хранятся как line1, line2, town, city и т.д., Что хорошо, но в другой половине он просто имеет один address, в котором хранится вся вещь!

Второй пример - даты. В некоторых таблицах у него есть секунды - с тех пор - даты Epoch, в других датах MySQL NOW(), а в других он буквально хранит его в 6 столбцах в строке - year, month, day, hour, minute, second - ouch...

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

  • С точки зрения программирования, как мы должны справиться с этим?. Для большого количества данных требуется динамическое форматирование (например, даты), поэтому мы думали о том, чтобы собирать данные по одной строке за раз, форматируя их правильно, затем повторно вставив его в нужные места в наших скриптах.

  • Скорость и эффективность запросов для нас не проблема,, так как нам нужно будет запускать это только один раз (после тестирования) на наших локальных машинах. Его база данных в настоящее время составляет ~ 800 МБ, когда SQL сбрасывается, но опять-таки много из этого - его бесполезные тестовые данные или просто совершенно ненужные.

Любые идеи о наилучшем способе борьбы с этим? Для справки наша система будет переписана на PHP, поэтому любые рекомендации на основе PHP были бы хороши. База данных в настоящее время (и по-прежнему будет) в MySQL.

4b9b3361

Ответ 1

Здесь нет решения. Никакой магии. Просто напряженная работа.

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

У вас будет больше, чем просто проблемы с форматированием. У вас также будут проблемы с дублированием данных. Если у вас есть 12 таблиц с адресами, но только 1 клиент, какой адрес выигрывает?

Только это решение может упростить большую обработку (возможно, вы можете игнорировать другие адреса, кроме одного благословенного адреса, связанного, например, с записью основного клиента).

И это приведет вас к последней проблеме. "Не теряйте данные" во время преобразования.

Это, скорее всего, не стартер с первого дня, в зависимости от того, что означает "не потерять какие-либо данные". Например, если вы отбрасываете адреса, там есть потеря данных. Конечно, каждый компонент имеет адрес, но не обязательно тот, который у них был раньше. Прежде, чем они, возможно, все были идентичны, но также они не могут. Это будет очень грязно.

После того, как вы выполнили свое сопоставление и другие процессы, их кодирование прост на любом языке. Языки сценариев хорошо работают для этого. Вы можете загружать каждую из таблиц "как есть" в новую БД и записывать процедуры хранилища для преобразования. Что бы вы ни говорили. Ваше преобразование, вероятно, будет несколько шагов, и большая часть этого кода, вероятно, будет "отключена" исключительно для облегчения преобразования.

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

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

Ответ 2

Первым шагом при перезаписи является полное понимание текущей структуры данных и кода, который выполняется над ним. Могут быть некоторые данные, которые кажутся излишними, но для этого кода требуется, чтобы это было по какой-то нечетной причине. Это плохой дизайн? Вероятно, но убедитесь, что вы полностью понимаете каждый бит кода, который пишет или получает доступ к данным, поэтому вы можете определить, что можно отбросить, что нужно реорганизовать и что нужно оставить как есть.

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

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

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

Ответ 3

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

Общие подсказки

  • Перед началом работы убедитесь, что вы понимаете существующую модель данных и требования к новой версии системы.
  • Создайте новую схему базы данных как можно лучше и попытайтесь не подчеркнуть себя тем фактом, что вам нужно перенести старый контент.
  • Используйте фреймворк с твердой ORM. Мало того, что будет легче разрабатывать новую версию, но миграция будет намного проще.

Миграция

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

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

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

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

Основной script (т.е. legacy/bin/full-migration) должен выполнить весь процесс (т.е. получить новую копию устаревшей производственной БД, (повторно) создать в ней новую БД и таблицы, запустить всю миграцию) и это должен быть тот же процесс, что и в конечном итоге после развертывания новой версии на рабочем сервере (только с другой конфигурацией). Это позволит вам тщательно протестировать его в своей среде разработки.

Поскольку для преобразования может потребоваться много времени, полезно регистрировать каждое действие (простое print action + object_id должно делать). Часто есть несколько строк, которые имеют некоторые неожиданные отличия, которые вызывают потерю script или вызывают ошибку целостности ссылки. В таких случаях хорошо видно, какой именно объект был таким, чтобы вы могли сразу перейти к БД, проверить данные, обновить script и снова запустить неудачный шаг.

Одна вещь, которая мне очень полезна, заключалась в том, чтобы определить классы моделей для таблиц старых баз данных, используя ORM. Я сделал это пару раз в Django, который поддерживает несколько соединений с базами данных и маршрутизацию по каждой модели, поэтому я смог написать сценарии, которые выглядели примерно так (Python):

from legacy import models as old
from catalog import models as new

# Loop through all products from the legacy DB
for old_product in old.Product.objects.all():  
    # Create an instance of the new product model class
    new_product = new.Product() 
    # Copy and modify attributes as needed
    new_product.name = old_product.product_name.strip()
    # ...
    # Save it to the new database
    new_product.save()

Кроме того, чем более ограничительна новая схема, тем лучше (т.е. NOT NULL, где это возможно, проверка внешнего ключа и т.д.), потому что это поможет вам увидеть, где ваши предположения о старой схеме неверны, а также предотвратить неправильную данные от входа в вашу новую систему (InnoDB как сервер для MySQL - хорошая идея).

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

Ответ 4

О чем подумать...

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

Это означает, что у вас есть две базы клиентских кодов на одни и те же данные, каждый из которых имеет свой собственный "API" в базе данных.

Это также означает, что старая система никогда не отключается на "go live".

Ответ 5

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

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

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

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

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

Есть много работы, и 3 месяца чрезвычайно трудны для такого рода миграции. Удачи.