web-dev-qa-db-fra.com

Quelles sont les meilleures pratiques concernant la suppression des colonnes de base de données obsolètes?

Je conçois une application qui, à un stade précoce, collectera les données A, B et C des clients, mais plus tard collectera plutôt les données A, B et D.

A, B, C et D sont très liés et existent actuellement en tant que colonnes d'une table de base de données PostgreSQL unique [~ # ~] t [~ # ~] .

Une fois que C n'est plus nécessaire, je veux supprimer ses références de mon application (j'utilise le Django ORM ), mais je souhaitez conserver les données déjà saisies. Quelle est la meilleure façon de le faire?

J'ai pensé à créer une nouvelle table pour ABD, mais cela signifie que cela pourrait causer des problèmes avec toutes les lignes référençant la table T.

Je pourrais simplement laisser la colonne C le long et supprimer les références à celle-ci dans le code, permettant aux données existantes de survivre.

Y a-t-il une meilleure option que je ne vois pas?

Quelques détails supplémentaires:

Le nombre de lignes ne sera pas important, probablement 1 à 2 par utilisateur. Il s'agit d'une application grand public, mais au moment où je passe du C au D, la base d'utilisateurs ne sera pas encore très grande. C et D ne seront probablement pas collectés en même temps, bien que ce soit une possibilité. C et D représentent probablement plusieurs colonnes chacune, pas seulement une chacune.

14
Jad S

Si vous souhaitez conserver les données, ce n'est pas obsolète. Laissez-le là où il est. C'est bien si une classe mappée à une table ne mappe pas chaque colonne.

31
kevin cline

OK donc votre situation est que vous voulez que les anciennes lignes aient la propriété C mais pas les nouvelles.

Cela équivaut à avoir une relation d'héritage de classe

class All
{
    string A;
    string B;
}

class Old : All
{
    string C;
}

class New : All
{
    string D;
}

que vous représenteriez dans la base de données avec trois tables avec des relations 1 à 1

table All
    id varchar
    A varchar
    B varchar

table Old
    id varchar
    C  varchar

table New
    id varchar
    D  varchar

Vous pouvez donc créer un script de migration pour créer la nouvelle ancienne table, y copier les données id et C et supprimer la colonne C de la table All.

Mettre à jour votre code comme requis avec le nouveau sql;

Alternativement, si vous avez juste besoin de pouvoir interroger les anciennes données C, vous pouvez créer une nouvelle table d'archivage avec A, B, C copier toutes les données et supprimer la colonne C, ajouter le col D à votre table 'Live'

8
Ewan

Si le stockage des données peut être un problème, divisez les tables: clé/clé A/B/clé C/D

Vous pouvez effectuer l'accès soit via une vue (définition de l'emplacement des données dans la base de données), soit en modifiant la définition ORM.

Ce n'est pas le plus performant (une jointure est impliquée), mais il peut présenter n'importe quelle combinaison d'A/B/C/D au fil du temps sans changer le stockage sous-jacent et en fonction de vos modèles d'accès réels, cela peut être suffisant.

Vous pouvez ne pas avoir la chance de pouvoir prendre des temps d'arrêt, restructurer des tables, etc. dans un système de production.

L'exécution de l'accès via la vue vous permet de passer de A/B/C à A/B/C/D à A/B/D dans la table sous-jacente avec un minimum de changement et aucun mouvement de données. Une vue sera transparente pour la logique de lecture et si votre dbms prend en charge des fonctions ou des vues pouvant être mises à jour, elle est également transparente pour la logique d'écriture.

Vraiment, je pense que votre décision reflétera de nombreuses préoccupations du monde réel: 1) quels sont les types de données C & D 2) les volumes de données relatifs collectés pour C/D 3) chevauchement relatif des données C/D par rapport aux entrées purement C ou D 4) Disponibilité et durée des fenêtres d'indisponibilité/maintenance 5) Prise en charge du SGBD pour les vues pouvant être mises à jour 6) Opportunité de conserver les détails de la structure physique de la base de données dans l'ORM par rapport à la rendre transparente en la présentant via des vues/fonctions dans la base de données (où elle est la même pour tous les accès applications, pas seulement celle actuelle)

Ma réponse est préférée pour les types de données volumineux/complexes pour (1), peu de chevauchement pour (3) et un temps d'arrêt minimal pour (4), idéalement avec un bon support dbms dans (5) et plusieurs applications accédant aux données dans (6)

Mais il n'y a pas de bon/mauvais pour beaucoup d'alternatives: - commencez par A/B/C, ajoutez plus tard D, ajustez l'ORM, supprimez encore plus tard la colonne C - commencez par A/B/C/D et ignorez les valeurs nulles etc. Je pense , considérez votre solution et ce que vous savez de son objectif/cycle de vie, modélisez la taille/le volume et attendez-vous à changer les choses plus tard, car tout ne tournera pas comme prévu.

2
simon coleman

Supprimer les références et rendre orphelines les données est une option à faible risque.

Il existe toujours des utilisations inconnues de la "porte dérobée" des données qui peuvent ou non être importantes à exposer en supprimant la colonne.

Selon le contenu de la colonne C, il peut y avoir un problème de performances mineur lorsque la base de données effectue en interne des analyses complètes de table ou tente de tirer la table entière en mémoire pendant les jointures si l'optimiseur considère que cela est plus efficace que l'utilisation d'index.

Les applications peuvent lire la table entière plusieurs fois plutôt que les colonnes sélectionnées - mais si vous utilisez exclusivement un ORM, cela est peu probable.

1
amelvin

Beaucoup de choses à considérer ici, mais vous voudrez peut-être envisager d'ajouter une vue pour superposer la table plutôt que d'apporter des modifications directement à la table. De cette façon, seule la vue doit changer.

Je ne sais pas Django ORM, mais cela pourrait être une possibilité.

1
Robbie Dee
  • Vous avez un tableau A avec les colonnes a, b, c.
  • Créez un nouveau tableau B avec les colonnes a, b, d.
  • Migrez vos données vers le tableau B.
  • Déplacez vos clés étrangères vers la table A vers la table B.

Vous pouvez maintenant utiliser le tableau B et vous avez toujours vos anciennes données pour référence.

0
Carra