Dois-je désactiver ou supprimer une ligne dans une base de données relationnelle?
Dans un nouveau programme où l'espace n'est pas vraiment un gros problème, est-il préférable de supprimer une ligne ou désactiver une ligne par, disons, d'une booléenne "Handicapés" et d'avoir le programme juste l'ignorer?
Par exemple, si je voulais supprimer un utilisateur d'un programme.
Vous devez vous connecter pour publier un commentaire.
Pas en les supprimant, vous créez une nouvelle classe de bugs pour toutes les futures requêtes. N'oubliez pas que la requête d'écriture est souvent fait par les utilisateurs (c'est à dire non-professionnels de l'informatique), et les développeurs juniors. Alors maintenant, chaque table qui contient des données incorrectes marquée seulement par un BIT indicateur actif aura besoin d'un supplément ET dans la clause where pour chaque requête à partir de maintenant jusqu'à l'éternité. Cela permettra d'aider les utilisateurs à tomber dans la fosse de l'échec au lieu de la fosse de succès. Cependant, je vous encourage fortement à mettre en œuvre ces drapeau de systèmes, de toute façon, parce que sans mauvaise conception, il n'est pas nécessaire pour l'entretien des développeurs pour corriger les nombreux bugs qu'il va créer.
La valeur c'est pour avoir des données historiques dans le tableau? Si l'entreprise si l'avenir, avoir les anciennes données dans les tableaux peut juste être un fardeau-- il causer des problèmes lors de la création de contraintes (de toutes les contraintes, devra être modifiée pour exclure les données que vous désirez n'était pas là). De la qualité des données est compliquée par le fait d'avoir continuellement ré-identifier ce qui est "vieux de la merde, nous avons peur de le supprimer mais ne veux plus jamais jamais utiliser ou mettre à jour de nouveau" et de nouveaux "trucs" nous nous soucions.
Est-il supprimé parce que c'était une erreur? Si la ligne correspond à une entité dans la vraie vie, c'est peut-être intéressant de garder et de définir un "vaporisé", "mort", "à gauche du bâtiment" pavillon. Si vous avez inséré une ligne qui correspond à aucune entité dans la vraie vie, une SUPPRESSION n'est pas une mauvaise chose. Sont imaginaires clients qui n'a jamais existé important de garder dans la table client?
Et enfin, la personnalité joue un grand rôle. Les gens peuvent être packrats avec des données, trop. Si un DBA conserve tous ses journaux de 30 ans en arrière, et n'aime pas la suppression de données, il devrait peut-être s'assurer qu'il est de rendre les données de décisions de conception sur la base des mérites et pas hors de propos de préférence personnelle.
Il dépend. (Mais vous l'avez deviné déjà, j'en suis sûr.)
Dans la pratique, la violation de l'utilisation correcte ici est presque toujours dans le sens de la suppression.
La principale mauvaise conséquence de la suppression est la façon dont il y a souvent dépendante des dossiers dans d'autres tables, dont l'intégrité référentielle est perdu lors de l'enregistrement parent s'en va.
Un hareng rouge utilisé pour défendre la suppression (que vous avez déjà traité correctement, en rejetant la question de la capacité de stockage), s'attend à ce que cela fera aucune différence notable dans la requête de l'efficacité.
Il y a trop de cas où l'utilisateur ou des problèmes de logiciel amener quelqu'un à besoin de toucher le gros bouton "Annuler"; si vous le supprimez, vous êtes hors de la chance (à moins d'obtenir de l'aide spéciale et à l'aggravation des gens que vous préférez à être gentils.)
La terminologie que j'utilise habituellement est "Actif" et "Inactif".
Un peu plus de points à prendre en considération (par Totophil):
Législation de protection des données pourrait exiger votre organisation, dans certaines circonstances, pour purger toutes les informations identifiables au sujet d'une personne. La législation diffère d'un pays à l'autre, certains pointeurs:
D'autre part, vous pourriez être tenu par la loi de garder certaines informations.
Après la lecture d'un livre sur le temporel conception de base de données, je suis venu à croire en l'idée que chaque enregistrement de la signification temporelle doit avoir au moins 4 colonnes timestamp. Ces quatre sont les suivants: créer, supprimer, démarrer à la fin. L'créés et supprimés les horodatages sont assez explicites. Votre système ne devraient pas regarder les enregistrements où est supprimé avant maintenant(). Le début et la fin des colonnes de déterminer quand les données s'appliquent à votre système. C'est pour garder un historique des modifications. Si vous avez besoin de mettre à jour un enregistrement, vous devez mettre la valeur de fin de l'heure à maintenant(), la copier, de la mise à jour de la copie, et l'ensemble de la copie de l'heure de début à maintenant(). De cette façon, lorsque vous avez besoin de regarder la façon dont une chose a été historiquement, le système peut comprendre. Vous pouvez également définir le début à un certain moment dans l'avenir, un changement de lieu automatiquement à l'époque, ou de définir la fin d'un temps futur pour avoir automatiquement disparaître à l'époque. Réglage de la créés/supprimés, les horodatages pour l'avenir n'a pas vraiment de sens...
Si vous utilisez un supprimée, visible, est actif, etc colonne, vous pouvez abstraction avoir à se rappeler de l'utiliser en utilisant des vues.
C'est à vous et à vos exigences (certaines choses deviennent un peu dur quand il existe des documents qui...ne le font pas).
Je dirais qu'une valeur de type boolean est un mauvais choix, bien que. Faire un nullable timestamp. C'est assez pratique pour savoir quand quelque chose a été supprimé, surtout quand vous avez supprimé trop et souhaitez annuler une partie de la supprimer.
Il dépend. Si elle est désactivée, alors il est plus facile de les récupérer /de voir que quelqu'un a bien supprimé le dossier (pour vérification).
Vous pouvez également avoir une exigence technique pour ne pas supprimer des enregistrements. Par exemple, si vous souhaitez synchroniser votre base de données avec un autre utilisateur par simple envoi d'enregistrements modifiés, vous ne seriez pas en mesure de le faire que si elle a effectivement été supprimé.
Vous devez l'avoir dans les exigences fonctionnelles. Si il n'est pas dit qu'il y explicitement, vous aurez à comprendre vous-même.
Dans la plupart des cas, il est préférable de stocker les enregistrements dans la table distincte. Ensuite, vous éviter des situations où un tableau fait référence à une autre table et vous devez décider si les dossiers dans le deuxième tableau, être traités comme supprimé ou pas.
Si vous aurez besoin des données supprimées parfois, mais pas très souvent: vous pouvez déplacer les enregistrements dans une base de données distincte/table (par exemple
users
etusers_deleted
, ou mieuxsomedb.users
etsomedb_deleted.users
).De cette façon, les données sont toujours accessibles par le biais d'une requête (bien que ce ne sera pas aussi simple que la normale), mais il n'a pas encombrer la base de données d'origine et vous n'avez pas de code autour d'elle.
L'ajout d'un "SUPPRIMÉ" de la colonne de votre table et le marquage des lignes au lieu de les supprimer crée beaucoup plus de travail pour vous avec peu (voire pas du tout) de prestations. Maintenant, chaque fois que vous écrivez une requête, vous devez n'oubliez pas d'inclure "OÙ SUPPRIMÉ n'EST PAS NULLE" (ou autre).
Une meilleure approche consiste à supprimer des données lorsque vous avez besoin de supprimer des données, et de compter sur votre processus de sauvegarde pour s'assurer que les données ne sont jamais perdues. Si pour une raison quelconque vous avez besoin de garder certaines données supprimées à portée de main (pour les recherches, peut-être), vous êtes mieux de simplement copier les données d'une autre table créée à cet effet puis de supprimer les originaux.
J'ai hérité de beaucoup de bases de données au fil des ans, et cette stratégie de repérage des dossiers au lieu de les supprimer est malheureusement très fréquent, et (dans mon expérience au moins) conduit toujours à des problèmes majeurs en bas de la route.
Sauf si vous avez un besoin spécifique pour la gestion de votre propre suppressions, vous êtes mieux de simplement supprimer les lignes.
Je tiens à noter qu'il y a (dans la plupart des pays) utilisez-cas où vous ne pouvez pas supprimer des enregistrements pour des raisons juridiques. L'industrie et les données de charge de cours.
Dans ce cas, je crois que la meilleure pratique guidleine est à l'ombre de la table de la "supprimé" les données qui vous gagne les avantages de la suppression effective décrites par MatthewMartin et, par extension, j'ai fini par trouver ce modèle souvent préférable à la création d' "active" bit-drapeaux à travers mes tables de données.
Ce devrait être déterminée par les besoins de l'application. Je l'ai fait dans les deux sens. J'ai quelques applications qui ont besoin de soutien annuler le coût de la suppression d'une ligne -- et les suppressions en cascade qui sont causées par qui-sont-trop cher pour ne pas l'avoir. Normalement, cependant, les applications que j'ai fait demander à l'utilisateur de confirmer la suppression, puis il suffit de faire ce que l'utilisateur a demandé. Dans certains cas, vous devez supprimer les données en raison de problèmes de confidentialité. C'est, si l'utilisateur demande à être retiré, vous devez vraiment le supprimer, ne pas se contenter de marquer qu'il n'est pas courant. Dans d'autres cas (comme d'impôt liés à des transactions), il peut être justifié de conserver les données dans un non-état actuel jusqu'à ce n'est plus requis par la loi. J'ai des applications qui s'intègrent dans les deux catégories.
Diverses stratégies peuvent être utilisées dans le cas où vous avez besoin de garder les "archives" de données. Selon qu'il doit être immédiatement disponible, vous pouvez le pousser pour archiver les tables qui sont soit maintenus ou sauvegardés et nettoyée régulièrement. Si il est nécessaire pour annuler vous voulez la conserver dans le tableau en cours, il suffit de marquer par un indicateur. Cela dépend vraiment de la complexité de votre schéma, les exigences de l'application, et de préférence personnelle, dans une certaine mesure.
C'est un appel de jugement, mais j'ai fini par l'ajout de "désactivé" colonnes sur les tables où j'ai déjà pensé que je pourrais juste supprimer la ligne. Je dirais que la plupart du temps, vous êtes plus sûr de l'ajout d'une colonne désactivé. Cela peut se complique avec n:n relations cependant, de sorte que c'est quelque chose à considérer.
Il est probablement préférable d'ajouter "supprimé" la colonne et offre aux utilisateurs de restaurer ou de purger les éléments supprimés.
Il dépend de la fonction de la base de données. Est-ce la source de toute vérité? Si oui, alors désactiver plutôt que de le supprimer, car il est plus facile de récupérer de la mauvaise exploitation (ie erreur de l'utilisateur). Si la base de données est l'aliment de certains en amont de la source de données, supprimer les données non utilisées. Tout les loisirs/la récupération peut être fait par le système en amont.
Comme beaucoup l'ont déjà dit, l'application a besoin de dicter ce que vous voulez faire. Mais pour moi, le marquage d'une ligne semble ne pas utiliser le bon outil pour la bonne chose. Peut-on logiquement penser à une suppression comme une SUPPRESSION, donc si vous n'êtes pas autorisé à supprimer, pour des raisons juridiques, alors vous ne pouvez pas le supprimer en premier lieu.
En même temps, je pense à toutes les données internes de la structure de maintien et d'indexation. Sans parler de toutes les optimisations qui peut être fait pour récupérer des données, mais en ajoutant que la case(dans la vue ou de la requête) affecte les performances de façon exponentielle avec la complexité de la base de données et les relations avec les entités ont.
En un mot, mettre la logique de suppression de la couche d'INTERFACE utilisateur pour éviter les erreurs de l'utilisateur et de donner de supprimer les autorisations pour les utilisateurs qui devrait être en mesure de le supprimer. L'utilisation des sauvegardes régulières pour garder les archives. Si votre application nécessite absolument une stricte vérification de l'histoire, de la mettre en œuvre dans les déclencheurs et de mettre de l'audit dans une base de données hors site pour éviter tout ce trafic, de vérifier et de la merde de la production.
Il y a deux autres solutions pour ce que j'ai couramment utilisés. Je suis d'accord avec d'autres personnes qui ont posté qu'il est vraiment à la hauteur des exigences de vos données.
Vous pourrait empêcher l'utilisateur de supprimer l'enregistrement si il sera la cause de l'intégrité référentielle des problèmes à l'aide de contraintes de clés étrangères (à condition que votre SGBDR soutient que). Quelques fois j'ai fourni un message à l'utilisateur final que "Vous ne pouvez pas supprimer ce <object> jusqu'à ce que vous dissocier <parent object> avec elle." Cela peut fonctionner aussi longtemps que vous n'avez pas anticiper il y a un énorme nombre d'associations avec une autre table ou des tables.
Une autre approche consiste à déplacer les dissocié des records pour être associées avec un dossier qui n'est pas supprimé. Par exemple, disons que vous avez un cours pour lequel 10 distinct des heures de cours y sont associés. Si vous supprimez le cours, vous pouvez permettre à l'utilisateur de décider si toutes les 10 classes sont supprimées, ou si elles sont associées à un existant ou nouveau cours.
Je suis entrain de créer un CRUD et je suis face au même problème.
Solution : Le D de CRUD devez désactiver au lieu de les supprimer.
Problèmes:
Gros Problème