Quelle est la meilleure façon de mettre en œuvre la suppression logicielle?
De travail sur un projet en ce moment et nous avons à mettre en œuvre la suppression logicielle pour la majorité des utilisateurs (rôles d'utilisateur). Nous avons décidé d'ajouter un is_deleted='0'
champ sur chaque table dans la base de données et mis à '1'
si particulier des rôles de l'utilisateur de frapper un bouton supprimer sur un enregistrement spécifique.
À l'entretien, à présent, à chaque SELECT
requête aurez besoin pour s'assurer qu'ils ne comprennent pas les documents where is_deleted='1'
.
Est-il une meilleure solution pour la mise en œuvre de la suppression logicielle?
Mise à jour: je tiens également à noter que nous avons une base de données d'Audit qui effectue un suivi des modifications (sur le terrain, ancienne valeur, la valeur à neuf, du temps, de l'utilisateur, ip) pour toutes les tables/champs dans la base de données d'Application.
Vous devez vous connecter pour publier un commentaire.
Vous pourriez effectuer toutes vos requêtes à l'encontre d'une vue qui contient le
WHERE IS_DELETED='0'
clause.Je pencherais vers un
deleted_at
de la colonne qui contient le datetime de lorsque la suppression a eu lieu. Ensuite, vous obtenez un peu de libre métadonnées à propos de la suppression. Pour votreSELECT
juste obtenir des lignesWHERE deleted_at IS NULL
Avoir
is_deleted
colonne est une assez bonne approche.Si c'est dans Oracle pour accroître encore les performances, je recommande partitionnement de la table en créant une liste de partition sur
is_deleted
colonne.Ensuite supprimé et non supprimé les lignes vont être physiquement dans des partitions différentes, même si pour vous ça va être transparent.
Par conséquent, si vous tapez une requête comme
puis Oracle va effectuer la " partition de l'élagage et de regarder dans la partition appropriée. En interne, une partition est une table différente, mais il est transparent pour l'utilisateur: vous serez en mesure de sélectionner à travers l'ensemble de la table, peu importe si il est partitionné ou pas. Mais Oracle sera en mesure de requête SEULE la partition il doit. Par exemple, supposons que vous avez 1000 lignes avec
is_deleted = 0
et 100000 lignes avecis_deleted = 1
, et la partition de la table suris_deleted
. Maintenant, si vous incluez conditionpuis Oracle s'analyser UNIQUEMENT la partition avec 1000 lignes. Si la table n'étaient pas partitionné, il aurait à balayer 101000 lignes (les deux partitions).
La meilleure réponse, malheureusement, dépend de ce que vous voulez accomplir avec votre douce suppressions et de la base de données vous êtes à la mise en œuvre de ce sein de.
Dans SQL Server, la meilleure solution serait d'utiliser un deleted_on/deleted_at colonne avec un type de SMALLDATETIME ou DATETIME (en fonction de la granularité nécessaire) et faire que la colonne nullable. Dans SQL Server, la ligne d'en-tête de données contient une valeur NULL masque de bits pour chacune des colonnes dans la table de sorte qu'il est légèrement plus rapide pour effectuer un is NULL ou is not NULL que c'est pour vérifier la valeur stockée dans une colonne.
Si vous avez un grand volume de données, vous voulez regarder dans le partitionnement des données, soit par le biais de la base de données elle-même ou par l'intermédiaire de deux tableaux distincts (par exemple, les Produits et ProductHistory) ou par l'intermédiaire d'une vue indexée.
Je évitent généralement le pavillon champs comme is_deleted, is_archive, etc, car ils portent un morceau de sens. Nullable deleted_at, archived_at champ fournit un niveau supplémentaire de sens pour vous et pour celui qui hérite de votre application. Et j'ai éviter le masque de bits des champs comme la peste car ils nécessitent une compréhension de la façon dont le masque de bits a été construit afin d'en saisir tout le sens.
si la table est grande, et la performance est un problème, vous pouvez toujours aller de "supprimer" les enregistrements d'une autre table, ce qui a des infos supplémentaires, tels que le temps de la suppression, qui a supprimé le dossier, etc
de cette façon, vous n'avez pas à ajouter une autre colonne de votre table primaire
Qui dépend des informations que vous avez besoin et quel est le flux de travail que vous voulez soutenir.
Voulez-vous être en mesure de:
Si l'enregistrement a été supprimé et l'onu-supprimé quatre fois, est-il suffisant pour vous de savoir qu'il est actuellement dans un un-état supprimé, ou voulez-vous être en mesure de dire ce qui s'est passé dans l'intervalle (y compris toute modification entre successives de suppressions!)?
Attention de soft-enregistrements supprimés entraînant l'unicité des violations de contrainte.
Si votre DB a des colonnes avec les contraintes unique, alors faites attention que l'état de la soft-enregistrements supprimés ne vous empêche pas de recréer l'enregistrement.
Pense du cycle:
Deuxième créer des résultats dans une violation de contrainte car login=JOE est déjà dans le soft-ligne supprimée.
Certaines techniques:
1. Déplacer l'enregistrement supprimé à une nouvelle table.
2. Faites votre contrainte d'unicité à travers le login et le deleted_at colonne timestamp
À mon avis, +1 pour passer à la nouvelle table. Sa prend beaucoup de
la discipline pour maintenir l' *ET delete_at = NULL,* sur tous vos
les requêtes (pour l'ensemble de vos développeurs)
Vous aurez certainement de meilleures performances si vous déplacez vos données supprimées à l'autre de la table comme Jim l'a dit, ainsi que d'avoir trace du moment où il a été supprimé, pourquoi, et par qui.
Ajoutant
where
deleted
=0 à toutes vos interrogations se ralentir de manière significative, et entravent l'utilisation de l'un quelconque des indices que vous pourriez avoir sur la table. Éviter d'avoir des "flags" dans vos tables de chaque fois que possible.vous ne mentionnez pas ce produit, mais SQL Server 2008 et postgresql (et d'autres j'en suis sûr) vous permettent de créer des index filtrés, de sorte que vous pouvez créer un index de couverture où is_deleted=0, l'atténuation de certains négatifs de cette approche particulière.
Quelque chose que j'utilise sur les projets est un statusInd tinyint not null default 0 colonne
à l'aide de statusInd comme masque me permet d'effectuer la gestion des données (suppression, archivage, de reproduire, de restauration, etc.). L'utilisation de ce dans les vues, je peux alors faire la distribution des données, édition, etc pour les applications gourmandes. Si la performance est un sujet de préoccupation de points de vue, l'utilisation de petites tables de faits à l'appui de cette information, l'abandon de la réalité, les gouttes de la relation et permet de scalled supprime.
Échelles et est centré sur des données en conservant les données de l'empreinte assez petit - clé pour 350gb+ dbs en temps réel avec des préoccupations. À l'aide des solutions de rechange, des tables, des déclencheurs a une surcharge, qui selon le besoin peut ou peut ne pas fonctionner pour vous.
SOX Vérifications connexes peut exiger plus d'un domaine à l'aide dans votre cas, mais cela peut aider.
Profitez de
Je préfère garder une colonne de statut, donc je peux l'utiliser pour différentes configs, c'est à dire publié, privé, supprimé, needsAproval...
Créer un autre schéma et de lui accorder toutes les données sur votre schéma.
Implment VPD sur votre nouveau schéma de sorte que chaque requête aura le prédicat permettant la sélection de la non-ligne supprimée seulement ajouté à la fin.
http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/cmntopc.htm#CNCPT62345
le mettre sur le dessus de votre
@entity
http://wiki.eclipse.org/EclipseLink/Examples/JPA/SoftDelete
Utiliser un affichage, une fonction ou une procédure qui vérifie
is_deleted = 0
; c'est à dire de ne pas sélectionner directement sur la table dans le cas où la table doit changer plus tard pour d'autres raisons.Et de l'indice de la
is_deleted
colonne pour les grandes tables.Puisque vous avez déjà une piste de vérification, de suivi de la date de suppression est redondant.