Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Относится к: SQL Server 2016 (13.x) и более поздние версии
База данных SQL Azure
Управляемый экземпляр SQL Azure
SQL Database в Microsoft Fabric
Темпоральные таблицы (также известные как системные темпоральные таблицы) — это функция базы данных, которая обеспечивает встроенную поддержку предоставления сведений о данных, хранящихся в таблице в любой момент времени, а не только правильных данных в текущий момент времени.
Начните работу с системно-версионируемыми темпоральными таблицами, а также ознакомьтесь с сценариями использования темпоральных таблиц.
Что такое темпоральная таблица с системным управлением версиями?
Темпоральная таблица с системным управлением версиями — это тип пользовательской таблицы, предназначенный для хранения полной истории изменений данных, что позволяет легко выполнять анализ состояния данных на определённый момент времени. Этот тип темпоральной таблицы называется системной темпоральной таблицей, так как система управляет периодом действия для каждой строки (то есть ядро СУБД).
В каждой темпоральной таблице есть два явно определенных столбца, каждый из которых имеет тип данных datetime2 . Эти столбцы называются столбцами периода. Столбцы периода используются исключительно системой для записи периода действия каждой строки при ее изменении. Главная таблица, в которой хранятся текущие данные, называется текущей таблицей, или просто темпоральной таблицей.
Помимо столбцов периода, в темпоральной таблице также содержится ссылка на другую таблицу с отзеркаленной схемой, которая называется таблицей журнала. Она используется в системе для автоматического сохранения предыдущей версии строки при каждом ее обновлении или удалении в темпоральной таблице. Во время создания темпоральной таблицы можно указать существующую таблицу журнала (которая должна соответствовать схеме) или разрешить системе создавать таблицу журнала по умолчанию.
Почему темпоральный?
Реальные источники данных являются динамическими, и в бизнес-решениях чаще всего используются сведения, которые аналитики могут получить из развития данных. Варианты использования темпоральных таблиц включают следующее.
- Аудит всех изменений данных и выполнение экспертизы данных при необходимости.
- Восстановление состояния данных на любой момент времени в прошлом.
- Вычисление тенденций во времени.
- Поддержка медленно изменяющегося измерения для приложений, связанных с поддержкой принятия решений.
- Восстановление после случайных изменений данных и ошибок приложений
Как работает Temporal?
Системное управление версиями для таблицы реализуется как пара таблиц: текущая таблица и таблица журнала. В каждой из этих таблиц для определения срока действия каждой строки используются два дополнительных столбца 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) на основе системных часов. При этом строка помечается как закрытая с записью периода, в течение которого была действительной предыдущая строка. Строка в текущей таблице удаляется. Запросы текущей таблицы не возвращают эту строку. Только запросы, которые имеют дело с данными журнала, возвратят данные, строка для которых была закрыта.Слияние: Операция ведет себя точно так же, как если бы были выполнены до трех инструкций (
INSERT,UPDATEи/илиDELETE), в зависимости от того, какие действия указаны в инструкцииMERGE.
Время, записанное в системных столбцах datetime2, основано на времени начала выполнения самой транзакции. Например, все строки, вставляемые в одну транзакцию, имеют одинаковое время в формате UTC, записанное в столбце, соответствующем началу SYSTEM_TIME периода.
При выполнении запросов на изменение данных в темпоральной таблице ядро СУБД добавляет строку в таблицу журнала, даже если значения столбцов не изменяются.
Как выполнить запрос для темпоральных данных?
Инструкция SELECT ... FROM <table> содержит новую конструкцию FOR SYSTEM_TIME с пятью темпоральными вложенными предложениями для запроса данных из текущих и исторических таблиц. Этот новый синтаксис инструкции SELECT непосредственно поддерживается для одной таблицы, распространяется на несколько соединений и на представления, построенные поверх нескольких темпоральных таблиц.
Когда вы выполняете запрос, используя предложение FOR SYSTEM_TIME с одним из пяти подпредложений, в результат включаются данные historical из темпоральной таблицы, как показано на следующем рисунке.
Приведенный ниже запрос ищет версии строк о сотруднике с условием фильтра 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 | Квалифицирование строк | Note |
|---|---|---|
AS OF
date_time |
ValidFrom <=
date_timeAND ValidTo >date_time |
Возвращает таблицу со строками, содержащими значения, которые являлись текущими в указанный момент времени в прошлом. Внутри системы объединение выполняется между темпоральной таблицей и таблицей журнала. Результаты фильтруются для возврата значений в строке, допустимой в момент времени, указанной параметром date_time . Значение строки считается допустимым, если значение system_start_time_column_name меньше или равно значению параметра date_time, а значение system_end_time_column_name больше значения параметра date_time. |
FROM
start_date_timeTOend_date_time |
ValidFrom <
end_date_timeAND ValidTo >start_date_time |
Возвращает таблицу со значениями для всех версий строк, которые были активны в течение указанного диапазона времени, независимо от того, начали ли они активны до значения параметра start_date_time аргумента FROM или перестали быть активными после значения параметра end_date_time для аргумента TO . На внутреннем уровне выполняется операция объединения между темпоральной таблицей и её исторической таблицей. Результаты фильтруются, чтобы возвращать значения для всех версий строк, которые были активными в любое время в течение указанного диапазона времени. Строки, которые перестали быть активными точно на нижней границе, определенной FROM конечной точкой, не включаются, а записи, которые стали активными точно на верхней границе, определенной TO конечной точкой, также не включаются. |
BETWEEN
start_date_timeANDend_date_time |
ValidFrom <=
end_date_timeAND ValidTo >start_date_time |
Аналогично предыдущему описанию FOR SYSTEM_TIME FROMstart_date_timeTOend_date_time, за исключением того, что таблица возвращаемых строк включает строки, которые стали активными на верхней границе, заданной конечной точкой end_date_time. |
CONTAINED IN(start_date_time, end_date_time) |
ValidFrom >=
start_date_timeAND ValidTo <=end_date_time |
Возвращает таблицу со значениями для всех открытых и закрытых версий строк в течение указанного диапазона времени, определенного двумя значениями периода для аргумента CONTAINED IN . Включаются строки, которые стали активными ровно на нижней границе интервала или перестали быть активными ровно на верхней границе интервала. |
ALL |
Все строки | Возвращает объединение строк, принадлежащих текущей и исторической таблицам. |
Скрыть столбцы периода
Можно скрыть столбцы периода, чтобы запросы, которые на них не ссылаются явно, не возвращали эти столбцы (например, при выполнении SELECT * FROM <table>).
Чтобы вернуть скрытый столбец, явно укажите его в запросе. Аналогично операторы INSERT и BULK INSERT продолжают работать так, как будто этих новых столбцов периода не существовало (при этом значения столбцов заполняются автоматически).
Подробнее об использовании предложения HIDDEN см. в CREATE TABLE и ALTER TABLE.
Samples
ASP.NET. Сведения о создании темпорального приложения с помощью темпоральных таблиц см. в веб-приложении ASP.NET Core.
Пример базы данных AdventureWorks: скачайте базу данных AdventureWorks для SQL Server, которая включает функции темпоральной таблицы.
Связанный контент
- Особенности и ограничения темпоральной таблицы
- Управление хранением исторических данных в системных темпоральных таблицах
- Секционирование с использованием темпоральных таблиц
- Проверки согласованности систем темпоральных таблиц
- Безопасность темпоральной таблицы
- Представления и функции темпоральных метаданных таблицы
- Работа с системно-версионными темпоральными таблицами, оптимизированными для памяти
- Создание системной темпоральной таблицы
- Изменение данных в системной темпоральной таблице
- Запрос данных в системной темпоральной таблице
- Начало работы с системными темпоральными таблицами
- Системно-версионируемые темпоральные таблицы с таблицами, оптимизированными для работы в памяти
- Начало работы с темпоральными таблицами в SQL Azure