Unix Technical Forum

History/audit without history tables

This is a discussion on History/audit without history tables within the SQL Server forums, part of the Microsoft SQL Server category; --> I am working on an application development project where another developer is responsible for the design of the SQL ...


Go Back   Unix Technical Forum > Database Server Software > Microsoft SQL Server > SQL Server

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 03-04-2008, 06:23 AM
Bill E.
 
Posts: n/a
Default History/audit without history tables

I am working on an application development project where another
developer is responsible for the design of the SQL Server 2005
database. Instead of allowing inserts or updates, many important
tables are designed so that "old" versions of records are maintained
in the table and marked as "inactive" using a bit column. For
example, if a user enters his address and then updates it five times,
we will be left with six address records, one of which is active.

I've never used this approach. I typically create a separate table to
capture change history. In my experience, change history is rarely if
ever accessed.

My concern is that this database will eventually handle millions of
customers and these tables will contains millions of "dead" records
SQL Server will need to sift through. It is true that we'll having
indexes on important columns (i.e., CustomerID) so perhaps I shouldn't
worry about it. Nevertheless, I wonder whether this approach is good
practice.

Bill E.
Hollywood, FL
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 03-04-2008, 06:23 AM
Plamen Ratchev
 
Posts: n/a
Default Re: History/audit without history tables

History/audit data is best kept in separate tables (and sometimes if
required can be even separate database).

A few cases may require the history data to be kept in the same table. For
example, in bill of material for parts you can keep old versions of the part
in the table. But history there is managed via a pair of start/end effective
dates which define the latest active part, and prior versions. This allows
to query the part to point of time and see how it was at particular date.

Also, using active/inactive flag only is not meaningful. It doesn't help to
see when this version was active and when it became inactive. Keeping a
period of active/inactive dates is normally a lot better and allows to
answer very easy queries like "What was the active version of this item by
that date?".

Partitioning could be another approach, but not sure applicable in your
case.

HTH,

Plamen Ratchev
http://www.SQLStudio.com

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 03-04-2008, 06:23 AM
Bill E.
 
Posts: n/a
Default Re: History/audit without history tables

Plamen,

Thanks for responding.

In fact, I have stored audit tables in a separate database on one
occasion. Also, I'm currently working on a database project where we
are storing contracts. We are going to keep contract pricing terms in
a way very similar to the way you handled your bill of materials--with
a start and end date. In this way, users will be able to store/view
contract terms for the same product/service as they apply today and
also as they applied in the past and will apply in the future.
However, I don't think of this as an "audit" function in the strict
sense because we are not really tracking changes to records. For
example, if someone enters pricing terms for a future date range and
then changes the price, I am not going to have a record of it.

One thing that I have to ensure is that overlapping date ranges for
the same product do not occur. I'm wondering how you handled this.
For example did you create a constraint in your database, did you
place a check in an update/insert trigger, did you handle it in a
stored procedure when the user entered a new part version or some
other approach?

Bill

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 03-04-2008, 06:23 AM
Erland Sommarskog
 
Posts: n/a
Default Re: History/audit without history tables

Bill E. (billmiami2@netscape.net) writes:
> I am working on an application development project where another
> developer is responsible for the design of the SQL Server 2005
> database. Instead of allowing inserts or updates, many important
> tables are designed so that "old" versions of records are maintained
> in the table and marked as "inactive" using a bit column. For
> example, if a user enters his address and then updates it five times,
> we will be left with six address records, one of which is active.
>
> I've never used this approach. I typically create a separate table to
> capture change history. In my experience, change history is rarely if
> ever accessed.
>
> My concern is that this database will eventually handle millions of
> customers and these tables will contains millions of "dead" records
> SQL Server will need to sift through. It is true that we'll having
> indexes on important columns (i.e., CustomerID) so perhaps I shouldn't
> worry about it. Nevertheless, I wonder whether this approach is good
> practice.


I would agree that this is not a design that I really like. Then again,
there may be business reasons for it that I don't know of.

One with it that I can see, is the code perform an update is simple:
mark the old row as inactive as when it happned and insert the new.
No need to do a separate insert to the history table. And if the
schema changes, you don't need to change the history table. Whether
these advantages are really worth it, I'mt not so sure.

In any case, I think you should add an indexed view which holds the active
rows, or else there can easily be bugs when programmers forgets to
include the "isactive = 1" condition in the query. At first glance your
colleague might find this attractive and argument for his idea. However,
there are some problems with indexed views. If you have:

select ... from indexedview where col = @val

SQL Server will first expand the view to the query, and then only use the
view in the query plan if both these are true: 1) it is able to match
the expanded query to the view 2) you are running Enterprise or Developer
Edition. You can circumvent this by adding the NOEXPAND hint, but then
there is one more thing that easily can be forgotten.

--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 03-04-2008, 06:23 AM
Erland Sommarskog
 
Posts: n/a
Default Re: History/audit without history tables

Bill E. (billmiami2@netscape.net) writes:
> One thing that I have to ensure is that overlapping date ranges for
> the same product do not occur. I'm wondering how you handled this.
> For example did you create a constraint in your database, did you
> place a check in an update/insert trigger, did you handle it in a
> stored procedure when the user entered a new part version or some
> other approach?


I would typically do this in a trigger. Here is a sample from a table
that I have:

CREATE TRIGGER pgm_ins_upd_tri ON pledgegroupmembership
FOR INSERT, UPDATE AS

IF EXISTS (SELECT *
FROM inserted i
JOIN pledgegroupmembership pgm ON i.accno = pgm.accno
AND i.startdate <> pgm.startdate
WHERE NOT ((i.startdate > coalesce(pgm.enddate, '99991231') OR
coalesce(i.enddate, '99991231') < pgm.startdate)))
BEGIN
ROLLBACK TRANSACTION
EXEC ael_handle_sp @@procid, 17, 'ERR_AEL_BOSINTERNAL',
'Internal error: overlapping intervals for the same account in pledgegroupmembership.'
RETURN
END





--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 03-04-2008, 06:23 AM
Plamen Ratchev
 
Posts: n/a
Default Re: History/audit without history tables

I normally prefer to handle the checking for overlaps (as well as the update
of the end date for the old occurrence) via a trigger. A few times clients
requested this to be done in the stored procedures handling the data update
(with the argument that somebody may disable triggers).

When archiving data in a way you to do not have to worry about overlaps.
Since the system automatically sets the date and time based on the system
clock, overlaps should not occur unless the system clock if not accurate. On
systems where the user sets the dates it is important to enforce the
checking.

HTH,

Plamen Ratchev
http://www.SQLStudio.com

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 03-04-2008, 06:23 AM
Bill E.
 
Posts: n/a
Default Re: History/audit without history tables

Plamen and Erland,

Thank you for your responses and suggestions.

Bill E.
Hollywood, FL

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #8 (permalink)  
Old 03-06-2008, 02:04 PM
--CELKO--
 
Posts: n/a
Default Re: History/audit without history tables

>> Instead of allowing inserts or updates, many important tables are designed so that "old" versions of records are maintained
in the table and marked as "inactive" using a BIT column. For
example, if a user enters his address and then updates it five times,
we will be left with six address records [sic: this confuses records
and rows] one of which is active. <<


>> I've never used this approach. <<


You are not old enough. Back in the early days of disk files, when we
still mimicked magnetic tapes and pre-allocated files with fixed or
variable length records, there would be a "deleted/active" bit flag at
the start of each physical record. The file system could set these
flags faster than it could over-write an entire record. Eventaully,
there were enough deleted records in a file that the system would run
a garbage collection routine (COMPRESS, COMPACT, DEFRAG or some such
name) to get rid of them, sort the file and re-index it.

>> I typically create a separate table to capture change history. In my experience, change history is rarely if ever accessed. <<


No, change history is done in a Data Warehouse,not an OLTP system.
What you want is an audit tool that gets this information from the log
file. Think about what a crash will destroy; think about how easy it
is to doctor audit trails for one person (instead of the two or more
required by law) with system access; now think about Feds coming to
visit.

>> My concern is that this database will eventually handle millions of customers and these tables will contains millions of "dead" records [sic:rows are not records] SQL Server will need to sift through. It is true that we'll be having indexes on important columns (i.e., customer_id) so perhaps I shouldn't worry about it. <<


Worry about it. It will hurt performance in a fast changing table.
YOu can often update a row in place; his kludge requires a disk write
for the flag and a disk write of the entire row.

>> Nevertheless, I wonder whether this approach is good practice. <<


It sucks
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 02:14 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com