How recording of every change of a row in a database is generaly stored?
The normal way do do audit logging of this sort is to have a shadow table and log changes with triggers on the base table you are auditing.  The other tables can be placed on a different physical disk if you need to to that for performance, and you can put indexes on them if you need to support quick retrieval of the data.

The tables will have roughly the same structure as your original tables, but will have a datetime column for when the change took place and a marker for whether the row was inserted, changed or deleted.  Sequencing the versions can be done by the time stamp.

The change date can be done by making the datetime column not null with a default of getdate(); an audit user column will capture the user with a not null column defaulted to Suser_Sname().  Assuming the actual user is being impersonated in the session this will capture the identity of the user making the change.  

The database has no way to be aware of the IP address connecting to a web server.  The application will have to explicitly capture and log the IP address with the transaction.  

If you have a large number of tables you wish to audit, you can use the metadata from the system data dictionary to generate the triggers programmatically.

This solution is by far the best for several reasons:


It captures any changes to the table, not just those made by the application.
The audit tables can be put on a different set of disks to reduce the I/O load on your primary tables.
You can use a view based on a union of the table and audit log table to that will show the entire history including the current version.
You can index the audit log tables as necessary so that the audit users can query them responsively.  As usual, index selection is a tradeoff between query performance and update overhead.