시스템 버전 임시 테이블 만들기Creating a System-Versioned Temporal Table

이 항목은 다음에 적용됩니다. 예SQL Server(2016부터)예Azure SQL Database아니요Azure SQL Data Warehouse아니요병렬 데이터 웨어하우스 THIS TOPIC APPLIES TO: yesSQL Server (starting with 2016)yesAzure SQL DatabasenoAzure SQL Data Warehouse noParallel Data Warehouse

기록 테이블을 지정하는 방법과 관련해서 시스템 버전 temporal 테이블을 만드는 다음 세 가지 방법이 있습니다.There are three ways to create a system-versioned temporal table with regards to how the history table is specified:

  • 익명 기록 테이블이 포함된 임시 테이블: 현재 테이블의 스키마를 지정하고 시스템이 자동 생성된 이름으로 해당 기록 테이블을 만들도록 합니다.Temporal table with an anonymous history table: you specify the schema of the current table and let the system create a corresponding history table with auto-generated name.

  • 기본 기록 테이블이 포함된 임시 테이블: 기록 테이블 스키마 이름 및 테이블 이름을 지정하고 시스템이 해당 스키마에 기록 테이블을 만들도록 합니다.Temporal table with a default history table: you specify the history table schema name and table name and let the system create a history table in that schema.

  • 미리 만든 사용자 정의 기록 테이블이 포함된 temporal 테이블: 요구에 가장 알맞은 기록 테이블을 만든 다음 temporal 테이블을 만드는 동안 해당 테이블을 참조합니다.Temporal table with a user-defined history table created beforehand: you create a history table that fits best your needs and then reference that table during temporal table creation.

익명 기록 테이블이 포함된 temporal 테이블 만들기Creating a temporal table with an anonymous history table

"익명" 기록 테이블이 포함된 temporal 테이블 만들기는 특히 프로토타입 및 시험 환경에서 빠른 개체 만들기에 편리한 옵션입니다.Creating a temporal table with an "anonymous" history table is a convenient option for quick object creation, especially in prototypes and test environments. 또한 SYSTEM_VERSIONING 절에 매개 변수가 필요하지 않으므로 temporal 테이블을 만드는 가장 간단한 방법이기도 합니다.It is also the simplest way to create a temporal table since it doesn’t require any parameter in SYSTEM_VERSIONING clause. 아래 예제에서는 기록 테이블의 이름을 정의하지 않고 시스템 버전 관리를 사용하도록 설정한 상태에서 새 테이블을 만듭니다.In the example below, a new table is created with system-versioning enabled without defining the name of the history table.

CREATE TABLE Department   
(    
     DeptID int NOT NULL PRIMARY KEY CLUSTERED  
   , DeptName varchar(50) NOT NULL  
   , ManagerID INT  NULL  
   , ParentDeptID int NULL  
   , SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL  
   , SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL  
   , PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime)     
)    
WITH (SYSTEM_VERSIONING = ON)   
;  

중요한 주의 사항Important remarks

  • 시스템 버전 temporal 테이블에는 기본 키가 정의되어 있어야 하며 PERIOD FOR SYSTEM_TIME 로 선언된 datetime2 열 두 개를 사용하여 정확히 한 개의 PERIOD FOR SYSTEM_TIME을 정의해야 합니다.A system-versioned temporal table must have a primary key defined and have exactly one PERIOD FOR SYSTEM_TIME defined with two datetime2 columns, declared as GENERATED ALWAYS AS ROW START / END

  • PERIOD 열은 null 허용 여부를 지정하지 않은 경우에도 언제나 null을 허용하지 않는다고 가정합니다.The PERIOD columns are always assumed to be non-nullable, even if nullability is not specified. PERIOD 열을 명시적으로 null 허용으로 정의한 경우 CREATE TABLE 문이 실패합니다.If the PERIOD columns are explicitly defined as nullable, the CREATE TABLE statement will fail.

  • 기록 테이블은 언제나 열 수, 열 이름, 순서 및 데이터 형식에서 현재 또는 temporal 테이블과 스키마를 맞춰야 합니다.The history table must always be schema-aligned with the current or temporal table, in terms of number of columns, column names, ordering and data types.

  • 익명 기록 테이블은 자동으로 현재 또는 temporal 테이블과 같은 스키마에 생성됩니다.An anonymous history table is automatically created in the same schema as current or temporal table.

  • 익명 기록 테이블 이름의 형식은 MSSQL_TemporalHistoryFor_<current_temporal_table_object_id>_[suffix]입니다.The anonymous history table name has the following format: MSSQL_TemporalHistoryFor_<current_temporal_table_object_id>_[suffix]. 접미사는 선택 사항이며 테이블 이름의 첫 번째 부분이 고유하지 않은 경우에만 추가됩니다.Suffix is optional and it will be added only if the first part of the table name is not unique.

  • 기록 테이블은 rowstore 테이블로 생성됩니다.The history table is created as a rowstore table. 페이지 압축은 가능하면 적용되며, 그렇지 않으면 기록 테이블을 압축하지 않습니다.PAGE compression is applied if possible, otherwise the history table will be uncompressed. 예를 들어 스파스 열과 같은 일부 테이블 구성은 압축을 허용하지 않습니다.For example, some table configurations, such as SPARSE columns, do not allow compression.

  • 기본 클러스터형 인덱스는 형식 IX_<history_table_name>의 자동 생성된 이름을 가진 기록 테이블에 대해 생성됩니다.A default clustered index is created for the history table with an auto-generated name in format IX_<history_table_name>. 클러스터형 인덱스는 PERIOD 열(시작, 종료)을 포함합니다.The clustered index contains the PERIOD columns (end, start).

  • 현재 테이블을 메모리 최적화 테이블로 만들려면 메모리 최적화 테이블을 포함한 시스템 버전 temporal 테이블을 참조하세요.To create the current table as a memory-optimized table, see System-Versioned Temporal Tables with Memory-Optimized Tables.

기본 기록 테이블이 포함된 temporal 테이블 만들기Creating a temporal table with a default history table

이름 지정은 제어하면서 시스템이 기본 구성을 사용하여 기록 테이블을 만들도록 하려는 경우 기본 기록 테이블이 포함된 temporal 테이블을 만들면 편리합니다.Creating a temporal table with a default history table is a convenient option when you want to control naming and still rely on the system to create the history table with the default configuration. 아래 예제에서는 기록 테이블의 이름을 명시적으로 정의하고 시스템 버전 관리를 사용하도록 설정한 상태에서 새 테이블을 만듭니다.In the example below, a new table is created with system-versioning enabled with the name of the history table explicitly defined.

CREATE TABLE Department   
(    
     DeptID int NOT NULL PRIMARY KEY CLUSTERED  
   , DeptName varchar(50) NOT NULL  
   , ManagerID INT  NULL  
   , ParentDeptID int NULL  
   , SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL  
   , SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL  
   , PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)     
)   
WITH    
   (   
      SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.DepartmentHistory)   
   )   
;  

중요한 주의 사항Important remarks

기록 테이블은 명명된 기록 테이블에 명시적으로 적용되는 다음 규칙을 사용하여 "익명" 기록 테이블 만들기에 적용되는 것과 같은 규칙을 사용하여 생성됩니다.The history table is created using the same rules as apply to creating an "anonymous" history table, with the following rules that apply specifically to the named history table.

  • 스키마 이름은 HISTORY_TABLE 매개 변수에 필수입니다.The schema name is mandatory for the HISTORY_TABLE parameter.

  • 지정된 스키마가 없는 경우 CREATE TABLE 문이 실패합니다.If the specified schema does not exist, the CREATE TABLE statement will fail.

  • HISTORY_TABLE 매개 변수에 의해 지정한 테이블이 이미 있는 경우 스키마 일관성 및 임시 데이터 일관성측면에서 새로 생성된 temporal 테이블에 대해 유효성이 검사됩니다.If the table specified by the HISTORY_TABLE parameter already exists, it will be validated against the newly created temporal table in terms of schema consistency and temporal data consistency. 잘못된 기록 테이블을 지정하면 CREATE TABLE 문이 실패합니다.If you specify an invalid history table, the CREATE TABLE statement will fail.

사용자 정의 기록 테이블이 포함된 temporal 테이블 만들기Creating a temporal table with a user-defined history table

사용자 정의 기록 테이블이 포함된 temporal 테이블 만들기는 특정 저장소 옵션 및 추가 인덱스를 가진 기록 테이블을 지정하려는 경우에 편리한 옵션입니다.Creating a temporal table with user-defined history table is a convenient option when the user wants to specify a history table with specific storage options and additional indexes. 아래 예제에서는 생성될 temporal 테이블과 정렬된 스키마를 가진 사용자 정의 기록 테이블을 만듭니다.In the example below, a user-defined history table is created with a schema that is aligned with the temporal table that will be created. 이 사용자 정의 기록 테이블에 대해 포인트 조회를 위해 클러스터형 columnstore 인덱스 및 추가 비클러스터형 rowstore(Btree) 인덱스를 만듭니다.To this user-defined history table, a clustered columnstore index and additional non clustered rowstore (B-tree) index is created for point lookups. 이 사용자 정의 기록 테이블이 생성된 후 사용자 정의 기록 테이블을 기본 기록 테이블로 지정하는 시스템 버전 temporal 테이블이 생성됩니다.After this user-defined history table is created, the system-versioned temporal table is created specifying the user-defined history table as the default history table.

CREATE TABLE DepartmentHistory   
(    
     DeptID int NOT NULL  
   , DeptName varchar(50) NOT NULL  
   , ManagerID INT  NULL  
   , ParentDeptID int NULL  
   , SysStartTime datetime2 NOT NULL  
   , SysEndTime datetime2 NOT NULL   
);   
GO   
CREATE CLUSTERED COLUMNSTORE INDEX IX_DepartmentHistory   
   ON DepartmentHistory;   
CREATE NONCLUSTERED INDEX IX_DepartmentHistory_ID_PERIOD_COLUMNS   
   ON DepartmentHistory (SysEndTime, SysStartTime, DeptID);   
GO   
CREATE TABLE Department   
(    
    DeptID int NOT NULL PRIMARY KEY CLUSTERED  
   , DeptName varchar(50) NOT NULL  
   , ManagerID INT  NULL  
   , ParentDeptID int NULL  
   , SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL  
   , SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL     
   , PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime)      
)    
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.DepartmentHistory))   
;  

중요한 주의 사항Important remarks

  • 집계 또는 창 작업 기능을 채택하는 기록 데이터에 대해 분석 쿼리를 실행할 계획인 경우 기본 인덱스로 클러스터형 columnstore 만들기는 압축 및 쿼리 성능에 권장되는 옵션입니다.If you plan to run analytic queries on the historical data that employs aggregates or windowing functions, creating a clustered columnstore as a primary index is highly recommended for compression and query performance.

  • 기본 사용 사례가 데이터 감사(즉, 현재 테이블에서 단일 행에 대한 기록 변경 내용 검색)인 경우 클러스터형 인덱스를 가진 rowstore 기록 테이블을 만드는 것이 좋습니다.If the primary use case is data audit (i.e. searching for historical changes for a single row from the current table), then a good choice is to create rowstore history table with a clustered index

  • 기록 테이블은 기본 키, 외래 키, 고유 인덱스, 테이블 제약 조건 또는 트리거를 가질 수 없습니다.The history table cannot have a primary key, foreign keys, unique indexes, table constraints or triggers. 또한 변경 데이터 캡처, 변경 내용 추적, 트랜잭션 또는 병합 복제에 대해 구성할 수 없습니다.It cannot be configured for change data capture, change tracking, transactional or merge replication.

비임시 테이블을 시스템 버전 임시 테이블로 변경Alter Non-Temporal Table to be System-Versioned Temporal Table

사용자 지정 임시 솔루션을 기본 제공 지원으로 마이그레이션하려는 경우처럼 기존 테이블을 사용하여 시스템 버전 관리를 사용하도록 설정해야 하는 경우입니다.When you need to enable system-versioning using an existing table, such as when you wish to migrate a custom temporal solution to built-in support.
예를 들어 트리거를 사용하여 버전 관리를 구현하는 테이블 집합이 있을 수 있습니다.For example, you may have a set of tables where versioning is implemented with triggers. 임시 시스템 버전 관리 사용은 덜 복잡하며 다음과 같은 추가 이점을 제공합니다.Using temporal system-versioning is less complex and provides additional benefits including:

  • 변경할 수 없는 기록immutable history

  • 시간 여행 쿼리를 위한 새로운 구문new syntax for time-travelling queries

  • DML 성능 향상better DML performance

  • 유지 관리 비용 최소화minimal maintenance costs

    기존 테이블을 변환하는 경우 새 열을 처리하도록 설계되지 않은 기존 응용 프로그램에 대한 영향을 피하기 위해 HIDDEN 절을 사용하여 새 PERIOD 열을 숨기는 것을 고려하세요.When converting an existing table, consider using the HIDDEN clause to hide the new PERIOD columns to avoid impacting existing applications that are not designed to handle new columns.

비temporal 테이블에 버전 관리 추가Adding versioning to non-temporal tables

데이터를 포함하는 비temporal 테이블에 대해 변경 내용 추적을 시작하려면 PERIOD 정의를 추가하고 선택적으로 SQL Server가 만드는 빈 기록 테이블에 대한 이름을 입력해야 합니다.If you want to start tracking changes for a non-temporal table that contains the data, you need to add the PERIOD definition and optionally provide a name for the empty history table that SQL Server will create for you:

CREATE SCHEMA History;   
GO   
ALTER TABLE InsurancePolicy   
   ADD   
      SysStartTime datetime2(0) GENERATED ALWAYS AS ROW START HIDDEN    
           CONSTRAINT DF_SysStart DEFAULT SYSUTCDATETIME()  
      , SysEndTime datetime2(0) GENERATED ALWAYS AS ROW END HIDDEN    
           CONSTRAINT DF_SysEnd DEFAULT CONVERT(datetime2 (0), '9999-12-31 23:59:59'),   
      PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime);   
GO   
ALTER TABLE InsurancePolicy   
   SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = History.InsurancePolicy))   
;  

중요한 주의 사항Important remarks

  • SQL Server Enterprise Edition 이외의 모든 버전에서 데이터가 포함된 기존 테이블에 기본값을 가진 null이 허용되지 않는 열을 추가하는 경우 데이터 작업(메타데이터 작업)의 크기에 주의해야 합니다.Adding non-nullable columns with defaults to an existing table with data is a size of data operation on all editions other than SQL Server Enterprise Edition (on which it is a metadata operation). SQL Server Standard Edition에서 데이터가 포함된 큰 기존 기록 테이블의 경우 null이 아닌 열을 추가하면 작업 비용이 많이 들 수 있습니다.With a large existing history table with data on SQL Server Standard Edition, adding a non-null column can be an expensive operation.

  • 기간 시작 및 기간 종료 열에 대한 제약 조건을 신중하게 선택해야 합니다.Constraints for period start and period end columns must be carefully chosen:

    • 시작 열에 대한 기본값은 기존 행이 유효하다고 생각하는 시점을 지정합니다.Default for start column specifies from which point in time you consider existing rows to be valid. 미래의 datetime 포인트로 지정할 수 없습니다.It cannot be specified as a datetime point in the future.

    • 종료 시간은 지정된 datetime2 정밀도에 대한 최대값으로 지정해야 함End time must be specified as the maximum value for a given datetime2 precision

  • 기간을 추가하면 기간 열에 대한 기본값이 유효한지 확인하기 위해 현재 테이블에 대해 데이터 일관성 검사를 수행합니다.Adding period will perform a data consistency check on the current table to make sure that the defaults for period columns are valid.

  • SYSTEM_VERSIONING을 사용하도록 설정할 때 기존 기록 테이블을 지정하는 경우 현재 테이블과 기록 테이블 둘 다에 대해 데이터 일관성 검사가 수행됩니다.When an existing history table is specified when enabling SYSTEM_VERSIONING, a data consistency check will be performed across both the current and the history table. DATA_CONISTENCY_CHECK = OFF 를 추가 매개 변수로 지정하는 경우 이 과정을 건너뛸 수 있습니다.It can be skipped if you specify DATA_CONISTENCY_CHECK = OFF as an additional parameter.

기본 제공 지원으로 기존 테이블 마이그레이션Migrate existing tables to built-in support

이 예제에서는 기본 제공 임시 지원에 대한 트리거를 기반으로 기존 솔루션을 마이그레이션하는 방법을 보여 줍니다.This example shows how to migrate an existing solution based on triggers to build-in temporal support. 이 예제에서는 현재 사용자 지정 솔루션이 두 개의 분리된 사용자 테이블(ProjectTaskCurrentProjectTaskHistory)에서 현재 및 기록 데이터를 분할한다고 가정합니다.For this example, we assume that the current custom solution splits the current and historical data in two separate user tables (ProjectTaskCurrent and ProjectTaskHistory). 기존 솔루션이 단일 테이블을 사용하여 실제 및 기록 행을 저장하는 경우 이 예제와 같은 마이그레이션 단계 전에 데이터를 두 테이블로 분할해야 합니다.If your existing solution uses single table to store actual and historical rows, then you should split the data into two tables prior to the migration steps shown in this example:

/*Drop trigger on future temporal table*/   
DROP TRIGGER ProjectCurrent_OnUpdateDelete;   
/*Make sure that future period columns are non-nullable*/   
ALTER TABLE ProjectTaskCurrent ALTER COLUMN [ValidFrom] datetime2 NOT NULL;   
ALTER TABLE ProjectTaskCurrent ALTER COLUMN [ValidTo] datetime2 NOT NULL;   
ALTER TABLE ProjectTaskHistory ALTER COLUMN [ValidFrom] datetime2 NOT NULL;   
ALTER TABLE ProjectTaskHistory ALTER COLUMN [ValidTo] datetime2 NOT NULL;   
ALTER TABLE ProjectTaskCurrent   
   ADD PERIOD FOR SYSTEM_TIME ([ValidFrom], [ValidTo])   
ALTER TABLE ProjectTaskCurrent   
   SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.ProjectTaskHistory, DATA_CONSISTENCY_CHECK = ON))   
;  

중요한 주의 사항Important remarks

  • PERIOD 정의에 기존 열을 참조하면 암시적으로 해당 열에 대해 generated_always_type을 AS_ROW_STARTAS_ROW_END 로 변경합니다.Referencing existing columns in PERIOD definition implicitly changes generated_always_type to AS_ROW_START and AS_ROW_END for those columns.

  • PERIOD 를 추가하면 기간 열에 대한 기존 값이 유효한지 확인하기 위해 현재 테이블에 대해 데이터 일관성 검사를 수행합니다.Adding PERIOD will perform a data consistency check on current table to make sure that the existing values for period columns are valid

  • 기존 데이터에 대해 임시 일관성 검사를 적용하기 위해 DATA_CONSISTENCY_CHECK = ON 을 사용하여 SYSTEM_VERSIONING 을 설정하는 것이 좋습니다.It is highly recommended to set SYSTEM_VERSIONING with DATA_CONSISTENCY_CHECK = ON to enforce data consistency checks on existing data.

이 문서가 도움이 되었나요?Did this Article Help You? 여러분의 의견을 환영합니다.We’re Listening

어떤 정보를 찾고 계세요? 정보를 찾으셨나요?What information are you looking for, and did you find it? 여러분의 의견은 문서의 내용을 개선하는 데 많은 도움이 됩니다.We’re listening to your feedback to improve the content. 의견이 있으면 sqlfeedback@microsoft.comPlease submit your comments to sqlfeedback@microsoft.com

참고 항목See Also

임시 테이블 Temporal Tables
시스템 버전 관리 임시 테이블 시작 Getting Started with System-Versioned Temporal Tables
시스템 버전 관리된 임시 테이블에서 기록 데이터의 보존 관리 Manage Retention of Historical Data in System-Versioned Temporal Tables
메모리 액세스에 최적화된 테이블을 포함한 시스템 버전 임시 테이블 System-Versioned Temporal Tables with Memory-Optimized Tables
CREATE TABLE(Transact-SQL) CREATE TABLE (Transact-SQL)
시스템 버전 임시 테이블의 데이터 수정 Modifying Data in a System-Versioned Temporal Table
시스템 버전 임시 테이블의 데이터 쿼리 Querying Data in a System-Versioned Temporal Table
시스템 버전 임시 테이블의 스키마 변경 Changing the Schema of a System-Versioned Temporal Table
시스템 버전 임시 테이블에서 시스템 버전 관리 중지Stopping System-Versioning on a System-Versioned Temporal Table