IDENTITY_INSERT ON이 한 번에 하나의 테이블에만 허용되는 이유는 무엇입니까?


20

이 경우입니다 IDENTITY_INSERT가 한 번에 하나 개의 데이터베이스 테이블에 ON으로 설정하지만, 왜 할 수 있는가? IDENTITY열이 전역 적으로 고유하지 않기 때문에 동시에 둘 이상의 테이블에 ID를 삽입하여 발생할 수있는 위험한 상황을 생각할 수 없습니다 (적어도 IDENTITY INSERT로 일반적으로 퍼지하는 것보다 더 위험하지는 않습니다).

IDENTINS INSERT는 거의 사용되지 않지만 하드 한계의 이유는 무엇입니까?


1
아마도 억지력이 거의 사용되지 않습니까?
레무스 루사 누

@RemusRusanu 내가 생각했던 것 중 하나이거나 실수로 여러 테이블에서 II를 ON으로 두지 않도록하십시오.
Ben Brocka

@ 왜 여러 테이블에 실수로 두는 것이 실수로 한 테이블에 실수로 두는 것보다 나쁜가? 둘 다 같은 종류의 문제를 일으킬 수 있습니다. 귀하의 질문에 대해 정말로 궁금합니다. 억제력이 답이라고 생각하지 않거나 엔진에 더 많은 제한이있을 것입니다. 그러나 나는 당신이 이것을 자주해야한다고 생각한다면, 아마도 용의자가 있다는 것에 동의합니다.
Aaron Bertrand

@AaronBertrand는 Q에서 암시 한 것처럼 그렇지 않습니다. SQL Server는 예약 키워드로 열 이름을 지정하는 것과 같은 다른 많은 나쁜 관행을 허용하기 때문에 억제력에 대해서도 잘 모르겠습니다 (때로는 []를 사용하지 않더라도!)
Ben Brocka

@Ben 맞습니다. 그것은 당신을위한 것이 아니라 질문을 겪은 독자들을위한 것입니다.
Aaron Bertrand

답변:


12

어려운 일이라고 생각합니다. 항상 그대로 둘 수 있다면 왜 신원 필드가 있습니까?

그러나 실제로 몇 가지 제한 사항이 있습니다.

  • 해당 연결에서만 유지됩니다.
  • 연결 당 하나의 테이블에서만 설정 가능

연결 관련 제한 사항을 기반으로, 나는 주로 실수로 ON 상태로 남아 있지 않다고 생각합니다.

누군가가 테이블 중 하나에서 ID 삽입을 켠 경우 ID 필드의 무결성을 깨는 (일반적으로) 유효하지 않은 삽입이 수행되었다고 상상해보십시오.

제약 조건이나 고유 인덱스가 없으면 ID 필드에 중복 값이있을 수 있습니다.


1
+1 중복에 대한 마지막 요점이 많이 빠져 있다고 생각합니다. 사람들은 그들이 IDENTITY그것을 설정 하면 독특한 제약이된다고 생각합니다 . 그들이 시도하더라도 물론 반증하기 매우 쉽습니다.
Aaron Bertrand

@AaronBertrand 그러나 IDENTITY INSERT가 설정된 테이블에서 중복 ID 위험은 정확히 동일합니다. 왜 하드 한계입니까? 나는 그것이 연결에 대해서만 지속된다는 사실이 예방책으로 훨씬 더 합리적이라고 생각합니다.
Ben Brocka

중복 ID 문제가 하드 제한의 이유라고 제안하지 않았습니다.
Aaron Bertrand

6

내 생각에 그것은 구현으로 인한 제한이었습니다. 여러 테이블에서이 설정을 허용하면 잠재적 인 성능 저하가 발생했습니다.

이는 세션 매개 변수이므로 단일 테이블에서 설정을 활성화 할 수 있다는 것은 서버 측 세션에 저장하기위한 테이블 및 오브젝트 ID가 단순함을 의미합니다. IDENTITY_INSERT가 활성화되어 있지 않으면 0이고 테이블에 대한 databaseid + objectid의 코딩이 하나의 정수일 수도 있습니다.

세션 내에서 여러 테이블에 매개 변수를 설정하면 서버가 해당 오브젝트의 동적 목록을 저장하고 모든 삽입 명령문에 대해이를 점검 함을 의미합니다. 세션이 천 테이블에 대한 매개 변수를 활성화한다고 상상해보십시오.

  1. 이는 서버가 세션 변수에 1000 개의 항목을 할당했음을 의미합니다.
  2. 이는 또한 서버가이 세션의 모든 삽입 명령문에 대해 1000 개의 항목 목록을 확인해야 함을 의미합니다.

또한 set identity_insert on이 서버에서 성능 전체 성능에 영향을 미친 것으로 생각됩니다. sybase에는 " Identity Burning Set Factor "가있어 테이블의 ID 카운터 값을 한 번만 저장할 수 있습니다 (값은 메모리에 유지되고 한 번에 서버에 한 번 디스크에 기록됨) 종료). SQL Server는 동일한 코드를 기반으로하기 때문에 비슷한 최적화가있을 수 있지만 테이블에서 identity_insert를 활성화하면 서버가 모든 삽입에 대한 ID 값을 저장하도록 제한 할 수 있습니다. 그렇지 않으면 최대 간격 크기를 보장 할 수 없기 때문입니다. 따라서 하나의 세션이 한 테이블의 삽입에서 성능을 저하시키는 경우 이는 허용되지만 서버의 모든 auto_increment 테이블에서 성능이 저하 될 수는 없습니다.


+1 여기에 아마도 진실이 있습니다. 나는 한 번에 하나만 INSERT세션을 진행할 수 있기 때문에 간격 크기 인수를 구입하지 않으며 1000 만 개의 하드 코딩 된 IDENTITY값을 쉽게 삽입 할 수 있습니다 .
Aaron Bertrand

간격 크기는 충돌시 발생하는 상황과 관련이 있습니다. sybase에서 서버가 충돌하면 마지막 ID가 손실되고 (메모리에 있음) 간격을두고 다시 시작됩니다 (ID 굽기 설정 요소 참조)
Olivier S

따라서 SQL Server에서 ID 열로 1,000,000 개의 행을 삽입하거나 SET IDENTITY_INSERT활성화 된 상태에서 1,000,000 개의 하드 코딩 된 값으로 ID 열을 재정의하는 동안 엔진이 충돌하면 다른 문제가 발생한다고 제안 합니까? 간격 크기가 여러 테이블에 단일 테이블에 영향을 미치는 것과 다르게 다르게 영향을 미치지 않는다고 제안합니다.
Aaron Bertrand

내 추측-나는 이것에 대한 증거가 전혀 없다-테이블의 SET IDENTITY_INSERT는 각 삽입에서 자동 증가의 디스크에 기록을 강제한다는 것입니다. 근거는 삽입 값이 아무것도 할 수 있기 때문에, 서버는 고려하지 수 "나는 디스크에 쓰는 경우 확인 만 1,000 행되면, 충돌의 경우에 나는 안전하게 내가 마지막으로 저장 한 값으로 1000을 추가 할 수있다"는 것
Olivier S
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.