Question

Problème

Dans une application Web traitant des produits et des commandes, je souhaite maintenir des informations et des relations entre les anciens employés (utilisateurs) et les commandes qu'ils ont traitées. Je souhaite maintenir des informations et des relations entre les produits et les commandes obsolètes qui incluent ces produits.

Cependant, je veux que les employés puissent désencombrer les interfaces administratives, telles que l'élimination des anciens employés, des produits obsolètes, des groupes de produits obsolètes, etc.

Je pense à la mise en œuvre de la suppression douce. Alors, comment fait généralement cela?

Mes pensées immédiates

Ma première pensée est de coller un "flag_softdeleted Tinyint Not Null par défaut 0 "Colonne dans chaque tableau d'objets qui devrait être supprimé en douceur. Ou peut-être utiliser un horodatage à la place?

Ensuite, je fournis un bouton "show supprimé" ou "Undelete" dans chaque interface graphique pertinente. En cliquant sur ce bouton, vous inclurez des enregistrements supprimés en douceur dans le résultat. Chaque enregistrement supprimé a un bouton "restaurer". Est-ce que ça a du sens?

Tes pensées?

De plus, j'apprécierais tous les liens vers les ressources pertinentes.

Était-ce utile?

La solution

C'est comme ça que je fais. j'ai un is_deleted champ qui par défaut est 0. puis les requêtes vérifient simplement WHERE is_deleted = 0.

J'essaie de rester à l'écart de toute résolution dure autant que possible. Ils sont parfois nécessaires, mais j'en fais une fonctionnalité d'administration uniquement. De cette façon, nous pouvons nous débarrasser durement, mais les utilisateurs ne peuvent pas ...

Éditer: En fait, vous pouvez l'utiliser pour avoir plusieurs «couches» de suppression douce dans votre application. Donc, chacun pourrait être un code:

  • 0 -> Non supprimé
  • 1 -> Soft supprimé, apparaît dans des listes d'éléments supprimés pour les utilisateurs de la direction
  • 2 -> Soft supprimé, n'apparaît aucun utilisateur, sauf les utilisateurs d'administrateur
  • 3 -> n'apparaît que pour les développeurs.

Avoir les 2 autres niveaux permettra toujours aux gestionnaires et aux administrateurs de nettoyer les listes supprimées si elles sont trop longues. Et puisque le code frontal vérifie simplement is_deleted = 0, c'est transparent pour le frontend ...

Autres conseils

L'utilisation de traits mous est une chose courante à mettre en œuvre, et elles sont mortes utiles pour beaucoup de choses, comme:

  • Enregistrer les données d'un utilisateur lorsqu'il a supprimé quelque chose
  • Enregistrer vos propres données lorsque vous supprimez quelque chose
  • Gardez une trace de ce qui s'est réellement passé (une sorte d'audit)
  • etc

Il y a une chose que je veux souligner que presque tout le monde manque, et cela revient toujours pour vous mordre dans la pièce arrière. Les utilisateurs de votre application n'ont pas la même compréhension d'un effacer comme vous l'avez fait.

Ils sont différents degrés des suppressions. L'utilisateur typique supprime des trucs quand (s) il

  • Fait une détention et vouloir supprimer les mauvaises données
  • Ne veut plus voir quelque chose à l'écran

Le problème est que si vous n'enregistrez pas le intention De la suppression, votre application ne peut pas distinguer les données erronées (qui n'auraient jamais dû être créées) et les données historiquement correctes.

Jetez un œil aux données suivantes:

PRICES | item | price | deleted |
       +------+-------+---------+
       |   A  |  101  |    1    |
       |   B  |  110  |    1    |
       |   C  |  120  |    0    |
       +------+-------+---------+

Certains utilisateurs ne veulent pas afficher le prix de l'article B, car ils ne vendent plus cet article. Alors il le supprime. Un autre utilisateur a créé un prix pour l'article A par dénombrement, il l'a donc supprimé et a créé le prix de l'article C, comme prévu. Maintenant, pouvez-vous me montrer une liste des prix pour tous les produits? Non, car vous devez afficher des données potentiellement erronées (a), soit vous devez exclure tous les prix sauf actuels (C).

Bien sûr, ce qui précède peut être traité de plusieurs manières. Mon point est que TU besoin d'être très clair avec ce TU SIGNIFICATION par une suppression et assurez-vous qu'il n'y a aucun moyen pour les utilisateurs de le détourner. Une façon consisterait à forcer l'utilisateur à faire un choix (masquer / supprimer).

Si j'avais du code existant qui frappe ce tableau, j'ajouterais la colonne et changerais le nom de la table. Ensuite, je créerais une vue avec le même nom que la table actuelle qui sélectionne uniquement les enregistrements actifs. De cette façon, aucun du code existant ne se casse et vous pourriez avoir la colonne Soft Delete. Si vous souhaitez voir l'enregistrement supprimé, vous sélectionnez dans la table de base, sinon vous utilisez la vue.

Je viens toujours d'utiliser un supprimé colonne comme vous l'avez mentionné. Il n'y a vraiment pas beaucoup plus que cela. Au lieu de supprimer l'enregistrement, définissez simplement le supprimé champ vers vrai.

Certains composants que je construis permettent à l'utilisateur à afficher tous les enregistrements supprimés et à les restaurer, d'autres affichent simplement tous les enregistrements où supprimé = 0

Votre idée a du sens et est utilisée fréquemment en production, mais, pour l'implémenter, vous devrez mettre à jour pas mal de code pour tenir compte du nouveau champ. Une autre option pourrait être d'archiver (déplacer) les enregistrements "dissudés" à une table ou une base de données distincte. Cela se fait également fréquemment et fait du problème de la maintenance plutôt que de (re) programmation. (Vous pouvez faire réagir un déclencheur de table à la suppression pour archiver l'enregistrement supprimé.)

Je ferais l'archivage pour éviter une mise à jour majeure du code de production. Mais si vous souhaitez utiliser un champ de plateau supprimé, utilisez-le comme horodatage pour vous donner des informations utiles supplémentaires au-delà d'un booléen. (Null = non supprimé.) Vous pouvez également souhaiter ajouter un champ supprimé pour suivre l'utilisateur responsable de la suppression de l'enregistrement. L'utilisation de deux champs vous donne beaucoup d'informations vous indique qui a supprimé quoi et quand. (La solution de champ supplémentaire est également quelque chose qui peut être fait dans une table / base de données d'archives.)

Le scénario le plus courant que j'ai rencontré est ce que vous décrivez, un tinyint ou même bit représentant un statut de IsActive ou IsDeleted. Selon que cela soit considéré comme des données «commerciales» ou de «persistance», il peut être cuit dans la logique d'application / domaine aussi transparente que possible, comme directement dans les procédures stockées et non connues du code d'application. Mais il semble que ce soit des informations commerciales légitimes pour vos besoins, il devrait donc être connu tout au long du code. (Afin que les utilisateurs puissent afficher les enregistrements supprimés, comme vous le suggérez.)

Une autre approche que j'ai vue est d'utiliser une combinaison de deux horodatages pour montrer une "fenêtre" d'activité pour un enregistrement donné. C'est un peu plus de code pour le maintenir, mais l'avantage est que quelque chose peut être programmé pour se supprimer en douceur à un moment prédéterminé. Les produits à durée limitée peuvent être définis de cette façon lorsqu'ils sont créés, par exemple. (Pour rendre un enregistrement actif indéfiniment, on pourrait utiliser une valeur maximale (ou juste une date future absurdement distante) ou simplement la date de fin null Si vous êtes d'accord avec ça.)

Ensuite, bien sûr, il y a davantage la prise en considération des choses supprimées / non supprimées de temps en temps et de suivre une sorte d'audit pour cela. L'approche du drapeau ne connaît que l'état actuel, l'approche d'horodatage ne connaît que la fenêtre la plus récente. Mais tout ce qui est aussi complexe qu'une piste d'audit devrait certainement être stockée séparément que les enregistrements en question.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top