Softdeletes mit Regeln in PostgreSQL

Es gibt immer mal wieder Gründe, gewisse Daten nicht unwiderruflich zu löschen. Manchmal ist es einfach, weil man selbst auch in der Zukunft noch wissen will, was in der Vergangenheit so los war. Es können aber auch Gesetze oder Regeln sein, die einen dazu zwingen. Da findet man dann so Sachen wie die Grundsätze der ordnungsgemässen Buchführung, die einem sinngemäss unter anderem sagen, dass man nichts löschen darf, was man einmal aufgeschrieben hat. Trotzdem kann es aber natürlich immer vorkommen, das ein Datensatz mal korrigiert werden muss, weil irgendwas falsch lief. Wenn dann mal jemand einen Datensatz erzeugt hat, der eigentlich nicht da sein sollte, will man den aber natürlich trotzdem wieder los werden, ohne mit dem Gesetz in Konflikt zu geraten. Hier kommt dann of das sogenannte “Soft Delete” ins Spiel, also die Markierung eines Datensatzes als gelöscht, statt ihn wirklich physisch zu löschen.

Am einfachsten geht das, indem man einfach ein UPDATE auf den entsprechenden Datensatz ausführt.

1
2
UPDATE TRANSACTION SET isdeleted=TRUE WHERE id=5
3

Intuitiv ist das aber nicht und noch dazu schützt es nicht vor einem voreiligen Datenbankadmin oder Programmiererkollegen, der dann doch mal mit Direktzugriff den Datensatz löscht, weil ihn jemand drum bittet und er nicht bedenkt, dass da nicht gelöscht werden sollte.

Als Alternative bietet es sich an, weiter mit dem DELETE-Statement zu arbeiten, aber statt des physischen Löschens ein Update auf den Datesatz durch eine Regel zu definieren.

1
2
CREATE RULE transaction_softdelete AS 
3
ON DELETE TO TRANSACTION DO INSTEAD
4
    UPDATE TRANSACTION SET isdeleted=TRUE WHERE id = OLD.id
5

Das allein schützt dann zwar immer noch nicht vor einem boshaften Admin, aber dem muss man dann eben mit Vertrauen oder feinerer Rechtezuweisung begegnen.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>