Каковы лучшие практики удаления устаревших столбцов базы данных? [закрыто]

14

Я разрабатываю приложение, которое на ранней стадии будет собирать данные A, B и C от клиентов, но позже вместо этого будет собирать данные A, B и D.

A, B, C и D очень связаны и в настоящее время существуют в виде столбцов одной таблицы T базы данных PostgreSQL .

Как только C больше не нужен, я хочу удалить его ссылки из моего приложения (я использую Django ORM ), но я хочу сохранить данные, которые уже были введены. Каков наилучший способ сделать это?

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

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

Есть ли лучший вариант, которого я не вижу?

Некоторые дополнительные детали:

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

Jad S
источник
Я думаю, что правильный подход к этому зависит от того, требуется ли вам различать строки, которые были собраны из {A, B, C}, и строки, собранные из {A, B, D}, и если да, если ваши текущие данные модель позволяет это. И это также будет зависеть от того, что вы собираетесь делать с этими строками, собранными из {A, B, C} - новая версия приложения отображает их как {A, B, D} с пустым «D», но пользователь не видит содержимое столбца C, у него может возникнуть искушение удалить эту строку из БД (если приложение позволяет удалять строки), поскольку он не видит содержимое.
Док Браун
Есть ли когда-нибудь строки с C и D, собранные одновременно? Или это всегда будет A, B, C, Null или A, B, Null, D? Если у вас есть C, D в одних и тех же строках в течение короткого периода ... в чем причина отсутствия таблиц A, B, C и A, B, D? Мы говорим ... сотни строк данных? Миллионы? миллиарды? Является ли время ответа фактором? Множество деталей, которые делают каждую ситуацию уникальной ...
WernerCD
@WernerCD добавил некоторые подробности о моем случае в вопросе
Jad S
Либо вы используете столбец, либо нет. Используйте это, держите это. Не бросайте это. Если вы хотите сохранить данные, переместите их в другую таблицу (без ограничения внешнего ключа) или экспортируйте.
Тайлон

Ответы:

31

Если вы хотите сохранить данные, то они не устарели. Просто оставь это там, где оно есть. Хорошо, если какой-то класс, сопоставленный с таблицей, не отображает каждый столбец.

Кевин Клайн
источник
1
через некоторое время вы можете получить множество пустых столбцов
Ewan
8
может быть, они могли бы попросить подход наилучшей практики на stackexchange .... когда это произойдет
Ewan
8
Я предполагаю, что мое раздражение от такого рода ответа состоит в том, что, конечно, вы можете сойти с рук, но его технический долг. В конце концов, вам нужно реальное решение, и вам не нужно объяснять всем новым сотрудникам, почему ваша лучшая в своем классе технологическая компания имеет случайные столбцы, которые не используются, разбросанные по вашей базе данных
Ewan
1
Я вижу точку @Ewan, но для моего случая использования это должно подойти. В моей голове это может быть слишком упрощено, но будет проще запустить скрипт переноса данных позже, если возникнет такая необходимость, скопировать данные C в новую таблицу со ссылкой на исходную строку в таблице T, а затем удалить столбцы C из таблицы T
Jad S
3
@Ewan - предположим, что устаревание столбца произойдет не один раз - это может произойти несколько раз, так как требования к дизайну обнаруживаются или изменяются. Если альтернативой пустому столбцу является разделение на отдельные таблицы (например, структуры наследования) каждый раз, когда столбец становится устаревшим, база данных будет завалена таблицами соединения для устаревших столбцов. Я считаю, что это может закончиться хуже.
Томас В.
8

Итак, ваша ситуация такова, что вы хотите, чтобы старые строки имели свойство C, а новые - нет.

Это эквивалентно наличию наследственных отношений класса

class All
{
    string A;
    string B;
}

class Old : All
{
    string C;
}

class New : All
{
    string D;
}

который вы представляете в базе данных с тремя таблицами с отношениями 1: 1

table All
    id varchar
    A varchar
    B varchar

table Old
    id varchar
    C  varchar

table New
    id varchar
    D  varchar

Таким образом, вы можете создать сценарий миграции для создания новой старой таблицы, скопировать в нее данные id и C и удалить столбец C из таблицы All.

Обновление вашего кода в соответствии с требованиями нового sql;

В качестве альтернативы, если вам просто нужно иметь возможность запрашивать старые данные C, вы можете создать новую таблицу Archive с A, B, C, скопировать все данные и удалить столбец C, добавьте D col в вашу таблицу 'Live'

Ewan
источник
1
Если бы я разделил таблицы, я бы предпочел взять три из них: {A, B} {C} {D}
Аконкагуа
что не соответствует примеру?
Эван
Подождите. я скучаю по чтению
Ewan
2

Если хранение данных может быть проблемой, то разделите таблицы: ключ / A / B ключ / C ключ / D

Вы можете получить доступ либо через представление (определение местоположения данных в БД), либо изменив определение ORM.

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

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

Выполнение доступа через представление позволяет переключаться с A / B / C на A / B / C / D на A / B / D в базовой таблице с минимальными изменениями и без перемещения данных. Представление будет прозрачным для логики чтения, и если ваша база данных поддерживает либо функции, либо обновляемые представления, то также прозрачно для логики записи.

Действительно, я думаю, что ваше решение отразит множество реальных проблем: 1) что такое типы данных C & D 2) относительные объемы данных, собранные для C / D 3) относительное перекрытие данных C / D по сравнению с чисто записями C или D 4) Доступность и продолжительность окна простоя / обслуживания 5) Поддержка СУБД для обновляемых представлений 6) Желательность сохранения деталей физической структуры БД в ORM против их прозрачности путем представления через представления / функции в БД (где она одинакова для всех обращающихся приложения, а не только текущее)

Мой ответ предпочтителен для больших / сложных типов данных для (1), небольшого перекрытия для (3) и минимального времени простоя для (4), в идеале с хорошей поддержкой dbms в (5) и множественных приложений, обращающихся к данным в (6)

Но для многих альтернатив нет правильного / неправильного: - начать с A / B / C, затем добавить D, настроить ORM, еще позже удалить столбец C - начать с A / B / C / D и игнорировать нули и т. Д. Я думаю, рассмотрите свое решение и то, что вы знаете о его предполагаемом назначении / жизненном цикле, проведите некоторое моделирование размера / объема и ожидайте, что все изменится позже, поскольку не все изменится так, как ожидалось.

Саймон Коулман
источник
1

Удаление ссылок и потеря данных - это вариант с низким риском.

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

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

Приложения могут читать всю таблицу несколько раз, а не выбранные столбцы, но если вы используете исключительно ORM, это маловероятно.

amelvin
источник
1

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

Я не знаю Django ORM, но это возможно.

Робби Ди
источник
2
ОП сказал, что они используют Postgres.
TripeHound
Спасибо - не увидел тег. Я отредактирую Q.
Робби Ди
0
  • У вас есть таблица A с колонками a, b, c.
  • Создайте новую таблицу B со столбцами a, b, d.
  • Перенесите ваши данные в таблицу B.
  • Переместите свои внешние ключи в таблицу A в таблицу B.

Теперь вы можете использовать Таблицу B, и у вас все еще есть старые данные для справки.

Карра
источник