Темпоральные таблицы
Область применения: SQL Server 2016 (13.x) и более поздних версий База данных SQL Azure Управляемый экземпляр SQL Azure
Темпоральные таблицы (также известные как системные темпоральные таблицы) — это функция базы данных, которая обеспечивает встроенную поддержку предоставления сведений о данных, хранящихся в таблице в любой момент времени, а не только правильных данных в текущий момент времени.
Начало работы с системными темпоральными таблицами и просмотром сценариев использования темпоральных таблиц.
Что такое темпоральная таблица с системным управлением версиями?
Темпоральная таблица с системным управлением версиями — это тип пользовательской таблицы, предназначенный для ведения журнала всех изменений данных, что позволяет легко выполнять анализ для определенной точки во времени. Этот тип темпоральной таблицы называется системной темпоральной таблицей, так как система управляет периодом действия для каждой строки (то есть ядро СУБД).
В каждой темпоральной таблице есть два явно определенных столбца, каждый из которых имеет тип данных datetime2 . Эти столбцы называются столбцами периода. Столбцы периода используются исключительно системой для записи периода действия каждой строки при ее изменении. Главная таблица, в которой хранятся текущие данные, называется текущей таблицей, или просто темпоральной таблицей.
Помимо столбцов периода, в темпоральной таблице также содержится ссылка на другую таблицу с отзеркаленной схемой, которая называется таблицей журнала. Она используется в системе для автоматического сохранения предыдущей версии строки при каждом ее обновлении или удалении в темпоральной таблице. Во время создания темпоральной таблицы можно указать существующую таблицу журнала (которая должна соответствовать схеме) или разрешить системе создавать таблицу журнала по умолчанию.
Зачем нужны темпоральные таблицы?
Реальные источники данных являются динамическими, и в бизнес-решениях чаще всего используются сведения, которые аналитики могут получить из развития данных. Варианты использования темпоральных таблиц включают следующее.
- Аудит всех изменений данных и выполнение экспертизы данных при необходимости.
- Восстановление состояния данных на любой момент времени в прошлом.
- Вычисление тенденций во времени.
- Поддержка медленно изменяющегося измерения для приложений, связанных с поддержкой принятия решений.
- Восстановление после случайных данных изменений и ошибок приложений.
Как работают темпоральные таблицы?
Системное управление версиями для таблицы реализуется как пара таблиц: текущая таблица и таблица журнала. В каждой из этих таблиц для определения срока действия каждой строки используются два дополнительных столбца datetime2 :
Столбец начала периода: система записывает время начала строки в этом столбце, обычно обозначаемую
ValidFrom
как столбец.Конечный столбец периода: система записывает время окончания строки в этом столбце, обычно обозначаемую
ValidTo
как столбец.
В текущей таблице содержится текущее значение для каждой строки. В таблице журнала содержатся все предыдущие значения (старые версии) для каждой строки и время начала и окончания промежутка, в котором действовали эти значения (если они заданы).
В следующем скрипте описан сценарий с данными сотрудника:
CREATE TABLE dbo.Employee (
[EmployeeID] INT NOT NULL PRIMARY KEY CLUSTERED,
[Name] NVARCHAR(100) NOT NULL,
[Position] VARCHAR(100) NOT NULL,
[Department] VARCHAR(100) NOT NULL,
[Address] NVARCHAR(1024) NOT NULL,
[AnnualSalary] DECIMAL(10, 2) NOT NULL,
[ValidFrom] DATETIME2 GENERATED ALWAYS AS ROW START,
[ValidTo] DATETIME2 GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME(ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeeHistory));
Дополнительные сведения см. в статье "Создание системной темпоральной таблицы".
Вставка. Система задает значение
ValidFrom
столбца на время начала текущей транзакции (в часовом поясе UTC) на основе системных часов и назначает значениеValidTo
столбца максимальному значению9999-12-31
. При этом строка помечается как открытая.Обновления: система сохраняет предыдущее значение строки в таблице журнала и задает значение
ValidTo
столбца для начала текущей транзакции (в часовом поясе UTC) на основе системных часов. При этом строка помечается как закрытая с записью периода, в течение которого строка была действительной. В текущей таблице строка обновляется со своим новым значением, а система задает значениеValidFrom
столбца для времени начала транзакции (в часовом поясе UTC) на основе системных часов. Значение обновленной строки в текущей таблице столбцаValidTo
остается максимальным.9999-12-31
Удаляет: система сохраняет предыдущее значение строки в таблице журнала и задает значение
ValidTo
для столбца время начала текущей транзакции (в часовом поясе UTC) на основе системных часов. При этом строка помечается как закрытая с записью периода, в течение которого была действительной предыдущая строка. Строка в текущей таблице удаляется. Запросы текущей таблицы не возвращают эту строку. Только запросы, которые имеют дело с данными журнала, возвратят данные, строка для которых была закрыта.Слияние: операция ведет себя точно так же, как если бы в инструкции выполнялось до трех операторов (а
UPDATE
INSERT
, а, или или)DELETE
в зависимости от того, что указано как действия в инструкцииMERGE
.
Время, записанное в системных столбцах datetime2, основано на времени начала выполнения самой транзакции. Например, все строки, вставляемые в одну транзакцию, имеют одинаковое время в формате UTC, записанное в столбце, соответствующем началу SYSTEM_TIME
периода.
При выполнении запросов на изменение данных в темпоральной таблице ядро СУБД добавляет строку в таблицу журнала, даже если значения столбцов не изменяются.
Как выполнить запрос для темпоральных данных?
Инструкция SELECT ... FROM <table>
имеет новое предложение FOR SYSTEM_TIME
с пятью темпоральными подклаузами для запроса данных в текущих таблицах и таблицах журнала. Этот новый SELECT
синтаксис инструкции поддерживается непосредственно в одной таблице, распространяется через несколько соединений и через представления поверх нескольких темпоральных таблиц.
При выполнении запроса с помощью предложения с помощью FOR SYSTEM_TIME
одного из пяти подклаузов будут включены исторические данные из темпоральной таблицы, как показано на следующем рисунке.
Приведенный ниже запрос ищет версии строк о сотруднике с условием фильтра WHERE EmployeeID = 1000
, которые были активны хотя бы часть промежутка между 1 января 2021 г. и 1 января 2022 г. (включая верхнюю границу промежутка):
SELECT * FROM Employee
FOR SYSTEM_TIME
BETWEEN '2021-01-01 00:00:00.0000000' AND '2022-01-01 00:00:00.0000000'
WHERE EmployeeID = 1000 ORDER BY ValidFrom;
FOR SYSTEM_TIME
фильтрует строки с периодом действия с нулевой длительностью (ValidFrom = ValidTo
).
Эти строки создаются при выполнении нескольких обновлений одного первичного ключа в одной транзакции. В этом случае темпоральные запросы возвращают только версии строк до выполнения транзакций и текущие версии строк после их выполнения.
Если необходимо включить эти строки в анализ, выполните запрос к таблице журнала напрямую.
В следующей таблице ValidFrom
в столбце "Квалифицирующие строки" отображается значение ValidFrom
в столбце, запрашиваемом таблице, и ValidTo
представляет значение ValidTo
в столбце, запрашиваемом таблице. Полный синтаксис и примеры см . в предложении FROM и JOIN, APPLY, PIVOT и запроса данных в системной темпоральной таблице.
Expression | Квалифицирование строк | Примечание. |
---|---|---|
AS OF date_time |
ValidFrom <= AND ValidTo > date_time date_time |
Возвращает таблицу со строками, содержащими значения, которые являлись текущими в указанный момент времени в прошлом. Внутри системы объединение выполняется между темпоральной таблицей и таблицей журнала. Результаты фильтруются для возврата значений в строке, допустимой в момент времени, указанной параметром date_time . Значение строки считается допустимым, если значение system_start_time_column_name меньше или равно значению параметра date_time, а значение system_end_time_column_name больше значения параметра date_time. |
FROM TO start_date_time end_date_time |
ValidFrom < AND ValidTo > end_date_time start_date_time |
Возвращает таблицу со значениями для всех версий строк, которые были активны в течение указанного диапазона времени, независимо от того, начали ли они активны до значения параметра start_date_time аргумента FROM или перестали быть активными после значения параметра end_date_time для аргумента TO . Внутри системы объединение выполняется между темпоральной таблицей и таблицей журнала. Результаты фильтруются, чтобы возвращать значения для всех версий строк, которые были активными в любое время в течение указанного диапазона времени. Строки, которые перестали быть активными точно на нижней границе, определенной FROM конечной точкой, не включаются, а записи, которые стали активными точно на верхней границе, определенной TO конечной точкой, также не включаются. |
BETWEEN AND start_date_time end_date_time |
ValidFrom <= AND ValidTo > end_date_time start_date_time |
Аналогично описанию FOR SYSTEM_TIME FROM start_date_time end_date_timeTO , кроме таблицы возвращаемых строк, содержатся строки, которые стали активными на верхней границе, определенной конечной точкой end_date_time. |
CONTAINED IN (start_date_time, end_date_time) |
ValidFrom >= AND ValidTo <= start_date_time end_date_time |
Возвращает таблицу со значениями для всех открытых и закрытых версий строк в течение указанного диапазона времени, определенного двумя значениями периода для аргумента CONTAINED IN . В эти строки включаются те, которые стали активными точно в нижнюю границу периода времени, и те, которые перестали быть активными точно в верхнюю границу периода времени. |
ALL |
Все строки | Возвращает объединение строк, принадлежащих текущей таблице и таблице журнала. |
Как скрыть столбцы периода
Можно скрыть столбцы периода, чтобы запросы, которые на них не ссылаются явно, не возвращали эти столбцы (например, при выполнении SELECT * FROM <table>
).
Чтобы вернуть скрытый столбец, явно укажите его в запросе. INSERT
Аналогично и BULK INSERT
операторы продолжаются так же, как если бы эти новые столбцы периода не присутствовали (и значения столбцов заполняются автоматически).
Дополнительные сведения об использовании HIDDEN
предложения см. в статье CREATE TABLE и ALTER TABLE.
Примеры
ASP.NET. Сведения о создании темпорального приложения с помощью темпоральных таблиц см. в веб-приложении ASP.NET Core.
Пример базы данных AdventureWorks: скачайте базу данных AdventureWorks для SQL Server, которая включает функции темпоральной таблицы.
Связанный контент
- Рекомендации и ограничения темпоральной таблицы
- Управление хранением исторических данных в системных темпоральных таблицах
- Секционирование с темпоральными таблицами
- Проверки согласованности систем темпоральных таблиц
- Безопасность темпоральной таблицы
- Представления и функции темпоральных метаданных таблицы
- Работа с темпоральными таблицами, оптимизированными для памяти
- Создание системной темпоральной таблицы
- Изменение данных в системной темпоральной таблице
- Запрос данных в системной темпоральной таблице
- Начало работы с системными темпоральными таблицами
- Системные темпоральные таблицы с оптимизированными для памяти таблицами
- Начало работы с темпоральными таблицами в База данных SQL Azure и Управляемый экземпляр SQL Azure