지원되지 않는 열에서 Identity 속성을 제거하는 이유


11

SQL Server 2000 이후에 ID 열을 "ID를 해제"하는 기능이 제거되었다는 것을 읽었습니다. 그리고 이것은 "디자인에 의한 것"입니다 (단지 빠진 기능이 아닙니다).

다음은 블로그에서 찾은 예 입니다. 시스템 테이블을 업데이트합니다. SQL Server 2000 이후에는이 기능이 제거되었습니다. 시스템 테이블을 통해이 작업을 수행하는 것은 좋지 않습니다. 다른 방법 으로이 기능을 사용하는 이유가 무엇인지 궁금합니다.

이 문제를 해결하면 상당한 양의 작업이 발생합니다. 다운 타임이 허용되지 않는 환경에서 수억 개의 행을 새 테이블에 복사합니다.

그래서 나는 "왜"를 물을 것이라고 생각했습니다.

Sql Server 2005 및 이후 버전에서 변경된 점은 무엇입니까? 아니면 항상 나쁘고 잠기지 않았습니까?

식별 컬럼을 다시 일반 컬럼으로 설정하여 "최상의 실습"(또는 유사한 원칙)을 위반하는 것은 무엇입니까?

-

"이 작업을 수행하는 이유"에 대한 요청에 대한 업데이트 :
이것은 매우 높은 수준의 요약입니다. 테이블에 파티션을 추가하기 시작합니다. (오래된 데이터를 아카이브 / 퍼지 할 수 있습니다.) 모두 쉽습니다. 그러나 때로는 레코드를 다른 파티션으로 옮겨서 제거하지 않도록 (파티션이 아카이브 / 삭제를 위해 나타날 때) 필요하지 않습니다. (파티션 열을 2 씩 늘려서 행을 다른 파티션으로 이동할 공간이 항상 있습니다.)

그러나 분할 열이 ID 열이면 값을 삭제하고 다시 삽입해야합니다 (ID 열의 값을 업데이트하는 방법은 없습니다). 복제 문제가 발생합니다.

따라서 ID 열 대신 시퀀스를 사용하고 싶습니다. 그러나이 스위치는 큰 데이터베이스에서는 매우 어렵습니다.

답변:


22

귀하의 질문은 본질적으로 다음과 같습니다.

처음부터 절대로 허용해서는 안되는 위험한 일을 더 이상 할 수없는 이유는 무엇입니까?

이 질문에 대한 대답은 크게 관련이 없습니다 (이 기능을 요구하는 이러한 Connect 항목에서 일부 Microsoft 의견을 볼 수는 있지만 # 294193# 252226).). 완전성을 위해, 나의 개요는 다음과 같습니다. identity 속성을 제거하는 기능은 시스템 테이블을 엉망으로 만드는 기능의 의도하지 않은 부작용이었습니다. 이것은 종종 매우 나쁜 결과를 초래 한 여러 가지 방식으로 사용되도록 의도되지 않았으므로 제거되었습니다. 문서화되지 않고 지원되지 않는 시스템 테이블 해킹이었습니다. 시스템 테이블에서 데이터를 변경하는 기능은 Microsoft가 더 이상 ID 열인 열에서 해킹하기를 원치 않았기 때문에 제거되지 않았습니다. 시스템 테이블과의 통합은 매우 위험하므로 제거되었습니다. IDENTITY 속성 자체를 제거하는 것은 특별히 대상이 된 기능 제거가 아니 었으므로 가능한 한 고대 에도이 접근법을 완전히 신뢰할 수 없었습니다.

즉, 우리는이 질문에 어떻게 대답합니까?

가동 중지 시간이 최소화되거나없는 열의 IDENTITY 속성을 어떻게 제거합니까?

이를 사용하여 쉽게 할 수있는 ALTER TABLE ... SWITCH, 내가 먼저 우리 자신의에서 배운 내가 확신 기술 폴 화이트연결 # 252226에 대한 해결 방법을 . 이 간단한 테이블을 감안할 때 빠른 예 :

CREATE TABLE dbo.Original
(
  ID INT IDENTITY(1,1) PRIMARY KEY,
  name SYSNAME
);
GO

INSERT dbo.Original(name) VALUES(N'foo'),(N'bar');
GO

SELECT * FROM dbo.Original;
GO

결과 :

ID  name
--  ----
1   foo
2   bar

이제 새도우 테이블을 작성하고이를 전환 한 다음 이전 테이블을 삭제하고 새 테이블의 이름을 바꾸고 정상적인 활동을 재개하겠습니다.

CREATE TABLE dbo.New
(
  ID INT PRIMARY KEY,
  name SYSNAME
);
GO

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
  ALTER TABLE dbo.Original SWITCH TO dbo.New;
  DROP TABLE dbo.Original;
  EXEC sys.sp_rename N'dbo.New', N'Original', 'OBJECT';
COMMIT TRANSACTION;
GO

INSERT dbo.Original(ID,name) VALUES(3,N'splunge');
UPDATE dbo.Original SET ID = 6 WHERE ID = 1;
GO

SELECT * FROM dbo.Original;
GO

결과 :

ID  name
--  -------
2   bar
3   splunge
6   foo

이제 정리하십시오 :

DROP TABLE dbo.Original;

이는 데이터 이동이없는 메타 데이터 작업 일 뿐이며 메타 데이터가 업데이트되는 동안 다른 사용자 만 차단합니다. 그러나 매우 간단한 예입니다. 외래 키가 있거나 복제, 변경 데이터 캡처, 변경 추적 등과 같은 다른 기능을 사용하는 경우이 변경을 수행하기 전에 일부 기능을 비활성화하거나 제거해야 할 수 있습니다 (모든 조합을 테스트 한 것은 아님). 외래 키에 대해서는 이 팁 을 참조 하여 스크립트를 생성하여 모든 외래 키 제약 조건을 삭제하고 다시 만드는 방법을 보여줍니다.

또한 SQL Server가이 열을 채우지 않도록 응용 프로그램 코드를 업데이트하고 열 순서 나 지정해야하는 열에 따라 삽입 또는 선택 문을 확인해야합니다. 일반적 으로이 표에 대한 언급을 위해 전체 코드베이스를 grep합니다.

또한 Itzik Ben-Gan (출처 : 이 고대 기사 ) 에서이 스크립트를 참조 하여이를 처리하는 다른 방법이 있지만 여기에는 데이터 이동이 포함되어 있으므로 "다운 타임이 최소이거나 최소"인 요구 사항을 제공하지 않습니다.


3
두 사람이 연결 항목을 찬성하도록 격려하고 싶습니다. ID 부울을 켜거나 끄는 ALTER COLUMN 기능을 구현하는 것이 얼마나 어려울 수 있습니까?! 해결하기가 고통 스럽습니다.
usr

어떤 이유로 든 ..SWITCH..적어도 하나의 파티션이 정의 된 테이블에서만 작동 한다고 생각 했습니다.
RBarryYoung

SWITCH테이블 분할에는 필요하지만 Enterprise Edition이 필요하지 않은 추가하고 싶습니다 .
Dan Guzman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.