먼저
당신은 아마 모든 세 개의 열 필요가 없습니다 old_id
, external_id
, new_id
. 에있는 new_id
열은에 IDENTITY
삽입하더라도 각 행에 대해 새 값이 생성됩니다 external_id
. 그러나, 사이 old_id
와 external_id
, 사람들은 거의 상호 배타적입니다 : 이미 존재 중 하나 old_id
값 또는 현재의 개념에 해당 열이, 바로 될 것입니다 NULL
사용하는 경우 external_id
나 new_id
. 이미 존재하는 행 (예 : old_id
값 이있는 행)에 새 "외부"ID를 추가 하지 않고에 대한 새 값이 들어오지 않으므로 old_id
사용되는 열이 하나있을 수 있습니다. 두 가지 목적을 위해.
따라서 external_id
열을 제거 하고 이름 old_id
을 바꾸십시오 old_or_external_id
. 이것은 실제 변경이 필요하지 않지만 일부 합병증을 줄입니다. external_id
앱 코드가 이미 삽입되도록 작성된 경우 "이전"값을 포함하더라도 열을 호출해야 할 수도 있습니다 external_id
.
새로운 구조는 다음과 같습니다.
PkId AS AS COALESCE(old_or_external_id, new_id, -1) PERSISTED NOT NULL,
old_or_external_id INT NULL, -- values from existing record OR passed in from app
new_id INT IDENTITY(2000000, 1) NOT NULL
이제 SPARSE
옵션 또는 데이터 압축을 사용하지 않는 경우 12 바이트 대신 행당 8 바이트 만 추가했습니다 . 또한 코드, T-SQL 또는 앱 코드를 변경할 필요가 없습니다.
둘째
이 단순화 과정을 계속하면서 우리가 남긴 것을 살펴 보겠습니다.
old_or_external_id
열은 이미 하나의 값을 가지거나, 또는 애플리케이션에서 새로운 값을 부여되거나, 방치한다 NULL
.
- 는
new_id
항상 생성 된 새 값이되지만, 경우에 그 값은 사용되는 old_or_external_id
열이다 NULL
.
old_or_external_id
및에 값이 필요한 시간은 없습니다 new_id
. 그렇습니다. 두 열에 모두 값 new_id
이있는 IDENTITY
경우가 있지만 해당 new_id
값은 무시됩니다. 이 두 필드는 상호 배타적입니다. 그래서 지금 무엇?
이제 왜 우리 external_id
가 처음에 필요한지를 살펴볼 수 있습니다 . 을 IDENTITY
사용하여 열에 삽입 할 수 있다는 것을 고려 SET IDENTITY_INSERT {table_name} ON;
하면 스키마를 전혀 변경하지 않고도 응용 프로그램 코드 만 수정하여 INSERT
명령문 / 연산 SET IDENTITY_INSERT {table_name} ON;
및 SET IDENTITY_INSERT {table_name} OFF;
명령문 을 래핑 할 수 있습니다 . 그런 다음 IDENTITY
열을 (새로 생성 된 값의 경우) 재설정 할 시작 범위를 결정 해야합니다. 더 높은 값을 삽입하면 다음 자동 생성 값이 발생하기 때문에 앱 코드가 삽입 할 값보다 훨씬 높아야합니다. 현재 MAX 값보다 커야합니다. 그러나 항상 IDENT_CURRENT 값 보다 작은 값을 삽입 할 수 있습니다 .
old_or_external_id
및 new_id
열을 결합 해도 2 개 또는 3 개의 열을 갖는 의도는 열을 기본 키 값으로 결합하기 때문에 그것들은 항상 고유 한 값입니다.
이 방법에서는 다음을 수행하면됩니다.
두 번째, 파트 B
바로 위에서 언급 한 접근 방식의 변형은 앱 코드가 -1로 시작하여 그로부터 내려가는 값을 삽입 하는 것입니다. 이것은 잎 IDENTITY
가는 유일한 사람 것으로 값을 최대 . 여기서 이점은 스키마를 복잡하게 할뿐만 아니라 앱 생성 값이 새로운 자동 생성 범위로 실행되는 경우 겹치는 ID로 실행되는 것에 대해 걱정할 필요가 없다는 것입니다. 마이너스 ID 값을 아직 사용하지 않는 경우에만 옵션입니다. 사람들이 자동 생성 열에 마이너스 값을 사용하는 경우는 거의 없으므로 대부분의 상황에서 가능성이 높습니다.
이 방법에서는 다음을 수행하면됩니다.
여기서는 여전히을 수행해야 IDENTITY_INSERT
하지만 새 열을 추가하지 않고 열을 "다시 시드"할 필요 IDENTITY
가 없으며 향후 겹칠 위험이 없습니다.
두 번째, 파트 3
이 접근 방식의 마지막 변형 중 하나는 IDENTITY
열을 교체 하고 대신 Sequences 를 사용하는 것 입니다. 이 방법을 사용하는 이유는 앱 코드가 양수, 자동 생성 범위 이상 (아래 아님) 및 필요없는 값을 삽입하도록하기 위해서 SET IDENTITY_INSERT ON / OFF
입니다.
이 방법에서는 다음을 수행하면됩니다.
- CREATE SEQUENCE를 사용하여 시퀀스 만들기
속성이 없지만 NEXT VALUE FOR 함수를 사용하여 제약 조건 이 IDENTITY
있는 새 열에 열을 복사하십시오 .IDENTITY
DEFAULT
PkId INT PRIMARY KEY CONSTRAINT [DF_TableName_NextID] DEFAULT (NEXT VALUE FOR...)
이렇게하면 8 또는 12가 아닌 각 행에 0 바이트가 추가됩니다.
- 앱에서 생성 된 값의 시작 범위는 자동 생성 된 값이 접근 할 수있는 수준보다 훨씬 높습니다.
- 앱 코드 인서트를 래핑
SET IDENTITY_INSERT {table_name} ON;
하고 SET IDENTITY_INSERT {table_name} OFF;
문으로 묶습니다 .
그러나 시퀀스 중 하나를 사용 SCOPE_IDENTITY()
하거나 @@IDENTITY
여전히 올바르게 작동 하는 코드의 요구 사항으로 인해 시퀀스로 전환하는 것이 현재 옵션이 아닙니다.