Storing history of full/partial tables
One way of doing this is to have a temporal table for business time (sometimes called valid time) as history. Basically what you have is a copy of your products table with additional attributes for begin_time and end_time:

CREATE TABLE PRODUCT_HISTORY
( ...
, BEGIN_TIME TIMESTAMP NOT NULL
, END_TIME TIMESTAMP
,    PRIMARY KEY (&lt;key&gt;, BEGIN_TIME) );


When you add a product you add a row to the history with BEGIN=now and END=null.

When a product changes you update the row where END=null to END=now, and add a new row as for insert.

When a product is removed update the row where END=null to END=now

All these manipulations of the history table are easily implemented via triggers.