[Dbix-class] "soft deletion"

Ash Berlin ash_cpan at firemirror.com
Mon Feb 16 23:39:08 GMT 2009


On 16 Feb 2009, at 23:23, Darren Duncan wrote:

> fREW Schmidt wrote:
>> I am sure there is a better term for this, I just don't know what  
>> it is.  I would like for my database to have some type of removal  
>> field that would effectively mark a row as deleted without deleting  
>> it.  I've seen ORMs that do this before and I was wondering if DBIC  
>> did something or had support for something like this.
>> To make myself more clear, I'd like either a binary flag or a date  
>> which would probably be called deleted or date_deleted or  
>> is_deleted (feel free to give input in this) and I'd like it not to  
>> show up in regular resultsets unless I explicitly say I want to see  
>> the deleted rows.
>
> Following up on other replies you got ...
>
> What I would do is something a little more generic, which is often  
> called auditing, and often makes use of a single extra table per  
> normal table.
>
> So the normal table holds only the current versions of live records  
> and no deleted records, and the audit table has copies of all the  
> records that used to exist as well as prior versions of changed  
> records, and often for completeness, also a duplicate of all  
> inserted and current records.  Note that a record update could also  
> be conceptually a delete followed by an insert.
>
> The point is that if your reason for a soft delete is to provide a  
> way to undo something destructive, then a delete isn't the only  
> common destructive action, but an update is too (and sometimes, so  
> is an insert).
>
> When I have done this before, generally only the live table had  
> unique keys etc on it as usual, and the corresponding audit table  
> did not.
>
> In one form, an audit table for table <foo> might have a name like  
> "<foo>_audit", or pick some other suffix you don't use elsewhere,  
> unless your database supports multiple schemas/namespaces in which  
> case you might use the same name in a different schema.
>
> Also if you want to easily associate changes to multiple tables as  
> an atomic database change, I also use a separate master table called  
> audit_change_set, which at least has fields audit_change_set_id (a  
> generated ordered unique id) and audit_date; if you track other  
> things like who made the change that can be extra fields here.
>
> Then in each table's audit table there are all the fields in the  
> normal table plus 2 more, audit_change_set_id and audit_action_type;  
> the latter containing one of [I,U,D].  For 'I' and 'U' the other  
> fields are a copy of the record post insert/update, and for 'D' the  
> other fields are a copy prior to delete; season to taste.
>
> The audit tables are populated effectively by triggers on the main  
> tables. Other than that, your normal code can just interact with the  
> main tables without knowing about the added complexity of the audit,  
> since no structure changes exist in the main tables.
>
> Using the audit tables to either display history or to recover the  
> database or individual records to an earlier state is left as an  
> exercise to the reader.
>
> Now I'm sure there are other good solutions, but this is what I did  
> on the last project I had that did change tracking for recovery or  
> 'history' queries.
>
> I also expect to make some changes to that design on my next  
> project, probably making the structure more resemble a version  
> control system like Git, where the database has versions and each  
> one knows what its parent versions are.  Now this isn't useful for  
> everyone, but for my application it would be, which involves people  
> making requests for data changes and others approving or rejecting  
> those changes for public consumption possibly with edits.
>
> -- Darren Duncan

Not sure if someone has mentioned this already or not, but http://search.cpan.org/~nuffin/DBIx-Class-Journal-0.900001_02/ 
  does some/most of the things you suggest.



More information about the DBIx-Class mailing list