Quelles sont les meilleures pratiques concernant le retrait des colonnes de base de données obsolètes? [fermé]

14

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 T unique .

Une fois que C n'est plus nécessaire, je souhaite supprimer ses références de mon application (j'utilise l' ORM Django ), mais je souhaite 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 et supprimer les références 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.

Jad S
la source
Je pense que la bonne façon d'aborder cela dépend si vous avez besoin de faire la distinction entre les lignes qui ont été collectées à partir de {A, B, C} et celles collectées à partir de {A, B, D}, et si oui, si vos données actuelles le modèle le permet. Et cela dépendra également de ce que vous allez faire avec ces lignes collectées à partir de {A, B, C} - la nouvelle version de l'application les affiche comme {A, B, D} avec un "D" vide, mais un l'utilisateur ne voit pas le contenu de la colonne C, il pourrait être tenté de supprimer cette ligne de la base de données (si l'application autorise la suppression des lignes), car il ne voit pas le contenu.
Doc Brown
Y a-t-il jamais des lignes avec C et D collectées en même temps? Ou ce sera toujours A, B, C, Null ou A, B, Null, D? Si vous avez C, D sur les mêmes lignes pendant une courte période ... quelle est la raison de ne pas avoir les tables A, B, C et A, B, D? Parlons-nous ... de centaines de lignes de données? Des millions? des milliards? Le temps de réponse est-il un facteur? Beaucoup de détails qui rendent chaque situation unique ...
WernerCD
@WernerCD a ajouté quelques détails sur mon cas dans la question
Jad S
Soit vous utilisez la colonne, soit vous ne l'utilisez pas. Utilisez-le, gardez-le. Ne le laisse pas tomber. Si vous souhaitez conserver les données, déplacez-les vers une autre table (sans contrainte de clé étrangère) ou exportez.
Thaylon

Réponses:

31

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.

Kevin Cline
la source
1
vous pourriez vous retrouver avec beaucoup de colonnes nulles après un certain temps
Ewan
8
ils pourraient peut-être demander une approche des meilleures pratiques sur stackexchange .... quand cela se produit
Ewan
8
Je suppose que mon ennui avec ce genre de réponse est que, bien sûr, vous pouvez vous en tirer, mais sa dette technologique. Finalement, vous voulez une vraie solution et vous n'avez pas à expliquer à toutes les nouvelles recrues pourquoi votre entreprise géante désormais la meilleure de sa classe a des colonnes aléatoires qui ne sont pas utilisées dispersées dans votre base de données
Ewan
1
Je vois le point de @Ewan, mais pour mon cas d'utilisation, cela devrait faire l'affaire. Les choses peuvent être trop simplifiées dans ma tête, mais il devrait être assez simple d'exécuter un script de migration de données plus tard, si nécessaire, pour copier les données C dans une nouvelle table en référence à la ligne d'origine dans la table T, puis supprimer les colonnes C de la table T.
Jad S
3
@Ewan - supposons que l'obsolescence des colonnes ne se produise pas une seule fois - elle peut se produire plusieurs fois, à mesure que les exigences de conception sont découvertes ou modifiées. Si l'alternative à une colonne nulle est de se diviser en tables distinctes (par exemple une structure d'héritage) chaque fois qu'une colonne devient obsolète, la base de données sera jonchée de tables de jointure pour les colonnes obsolètes. Je pense que cela risque fort de finir pire.
Thomas W
8

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 l'id et les données 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'

Ewan
la source
1
Si je partage des tables, je préfère en prendre trois: {A, B} {C} {D}
Aconcagua
cela ne correspond pas à l'exemple?
Ewan
attendez. la lecture me manque
Ewan
2

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 selon 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 plus tard la colonne C - commencez par A / B / C / D et ignorez les valeurs nulles etc. Je pense , tenez compte de votre solution et de 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.

Simon Coleman
la source
1

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

Il existe toujours des utilisations inconnues des portes dérobé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 de table complètes 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.

amelvin
la source
1

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 connais pas Django ORM, mais cela pourrait être une possibilité.

Robbie Dee
la source
2
OP a dit qu'ils utilisaient Postgres.
TripeHound
Merci - je n'ai pas vu de balise. Je vais modifier le Q.
Robbie Dee
0
  • 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.

Carra
la source