본문 바로가기

SQL Server/SQL Server Tip & Tech

날짜와 복합키를 이룬 IDENTITY 컬럼의 값 순환시키기

날짜 기준으로 테이블을 범위 파티셔닝하는 대량 로그 테이블인 경우,
날짜 컬럼과 IDENTITY속성의 컬럼을 PRIMARY KEY로 설정하게된다.

문제는... IDENTITY속성 컬럼의 데이터 타입이...
보통은 int일텐데...
int로 커버할 수 있는 약 21억건 - 양수만 따졌을 때 - 이 부족하다라고 주장하는 동료가 있을 수 있다는 점이다.
(하긴... 하루 115만건의 레코드를 5년간 보관하면 21억건 정도가 되긴한다.)

우리가 해결해야 하는 문제는 대충 이렇다.

1. 날짜를 기준으로 테이블을 범위 파티셔닝하고, 슬라이딩 윈도우를 구현한다.
2. 모든 테이블은 식별자를 가진다. 단, 날짜만으로는 Primary Key가 될 수 없다.
3. 가능한한 Primary Key 사이즈가 작았으면 좋겠다.
4. 하루 로그량은 수 백만건이라고 가정한다.
5. 로그 테이블은 회사 망하기 전까진 없애지 않는다. ㅡㅡ;;;;
6. IDENTITY 컬럼의 RESEED를 수동으로 하고 싶진 않다.

가능한 해결 방법이야 여러가지겠지만... 이렇게 하면 어떨까 싶다.

IDENTITY 속성의 int타입 컬럼을 날짜 컬럼과 함께 복합키로 설정하고...
로그 레코드를 INSERT하다가 int타입의 컬럼이 overflow를 일으키면 자동으로 Reseed한다.

간단한 얘긴데 썰이 너무 길었다. ㅡㅡ;


- 테스트 코드

IF OBJECT_ID(N'dbo.T1', 'U') IS NOT NULL

       DROP TABLE dbo.T1;

GO

 

CREATE TABLE dbo.T1 (

       seq int IDENTITY(2147483641, 1),

       logDate datetime DEFAULT(GETDATE()),

       CONSTRAINT PK_T1 PRIMARY KEY CLUSTERED (seq, logDate)

);

GO

 

BEGIN TRY

       INSERT dbo.T1 DEFAULT VALUES

END TRY

BEGIN CATCH

       IF ERROR_NUMBER() = 8115

             DBCC CHECKIDENT ("dbo.T1", RESEED, 0)

 

       INSERT dbo.T1 DEFAULT VALUES

END CATCH

 

SELECT * FROM dbo.T1

GO