Few suggestions for your setup
DB Setup
Use a temporary (staging) table to gather new records. Preferably you should range
partition
this table with the interval of your finest aggregation (e.g. minute) using the insert timestamp. Insert timestamp, contrary to the timestamp of the measurement (called sensor timestamp), is important to distinct - see the discussion below.
Define the detail table with the same partitioning schema using as the partitioning key the sensor timestamp.
Define the aggregated tables if required, partitioned on the the sensor timestamp. Check carefully what level you need. This is not
defined by the requested reports, but with the performance you can query the data.
E.g. 30 minutes levels seem to be an overkill, as you can effectively query it from the 15 minutes level.
Processing
The background job running once per minute processes one partition of the stating table (i.e. one minute delta) and
You should be careful here. Counts, sums and averages are no problems, but for distinct
counts you must use some implementation of HyperLogLog which will produce only estimated data.
You should also check if you must handle delayed data entries, i.e. case where in your delta are also data with older sensor timestamps.
You must refresh all aggregation intervals relevant for those timestamp.
Example: In your process data inserted at 10:01 the oldest sensor entry is 09:59, so you must refresh three minutes aggregation (09:59, 10:00 and 10:01) and
two 15 minutes aggregations (9:45 and 10:00) etc.
Daily Closing
To address the possible inaccuracy of the delta processing (see HyperLogLog above but including all other kinds), you can periodically
throw away the last part of the aggregation and recalculate them exactly from the detail table.
This will eliminate the problem of "error accumulation" - this concept is also know as Lambda Architecture.
Keeping the History
All tables have a defined a rolling window policy - i.e. how long the data will be kept.
The aggregated tables are controlled by the reporting requirements.
The detail table is used only as a backup if something goes wrong, you have the (limited) possibility to recover the aggregated data.
So set it so long as economically meaningful.
Old data is removed using DROP PARTITION
only (not with delete).
You may apply a cycle partitioning for the stating table, i.e. you use only time as partition key, not the date component.
This will simplify the partition maintenance - you will use TRUNCATE PARTITION
instead to remove the data.
Reporting
Your aggregation will be done say once per minute, this means the lowest aggregate is always consistent.
Contrary the last 15 minutes aggregate will be often incomplete, containing only few minutes of data.
You should design some normalizing concept to handle this problem. It is not nice to see that the number of successful events dropped significantly in the last quarter of an hour.
Good Luck!