You may care about changes to most columns in a table, but are not interested in tracking the changes to some of them. In this case, you can exclude columns using WITHOUT SYSTEM VERSIONING
when defining them. Note this is only available in MariaDB.
CREATE TABLE user (
id int,
level VARCHAR(20),
favorite_color VARCHAR(20) WITHOUT SYSTEM VERSIONING,
start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp),
PRIMARY KEY (id)
) WITH SYSTEM VERSIONING;
When changing the favorite_color
value, the system will not create a new row and update timestamps. Instead, it will change the favorite_color
value of the current row in place.
You may also have many columns in a table that don’t need versioning but want to version on a small subset of columns. Instead of having to mark the majority of your columns using WITHOUT SYSTEM VERSIONING
, you can use WITH SYSTEM VERSIONING
on a specific column. This automatically makes the table versioned and excludes other columns from being versioned. This feature is only available in MariaDB.
CREATE TABLE user (
id int,
level VARCHAR(20) WITH SYSTEM VERSIONING,
nickname VARCHAR(20),
date_of_birth DATE,
PRIMARY KEY (id)
);
#Storing History Separately Storing historical records alongside current records can impact performance due to the resulting overhead in table scans and index lookups. In order to reduce the impact on queries for current data, add a separate partition for historical rows. There must be exactly one current partition and at least one historical partition.
CREATE TABLE user (
id int,
status VARCHAR(20),
start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp),
PRIMARY KEY (id)
) WITH SYSTEM VERSIONING
PARTITION BY SYSTEM_TIME (
PARTITION user_historical HISTORY,
PARTITION user_current CURRENT
);
When using multiple historical partitions, it is possible to define when to roll to the next partition using either a row limit or a time interval:
/* Rolling over by row count */
CREATE TABLE user (
id int,
status VARCHAR(20),
start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp),
PRIMARY KEY (id)
) WITH SYSTEM VERSIONING
PARTITION BY SYSTEM_TIME LIMIT 500000 (
PARTITION user_historical_1 HISTORY,
PARTITION user_historical_2 HISTORY,
PARTITION user_current CURRENT
);
/* Rolling over by interval
CREATE TABLE user (
id int,
status VARCHAR(20),
start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp),
PRIMARY KEY (id)
) WITH SYSTEM VERSIONING
PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH (
PARTITION user_historical_1 HISTORY,
PARTITION user_historical_2 HISTORY,
PARTITION user_current CURRENT
);
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}