>> 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