고려해야 할 한 가지는 기본 키와 클러스터형 인덱스가 같지 않다는 것입니다. 기본 키는 제약 조건이며 데이터가 존재하는 규칙 (예 : 데이터 무결성)을 처리합니다. 효율성 / 성능과 관련이 없습니다. 기본 키를 사용하려면 키 열이 고유하고 (조합하여) NOT NULL (개별적으로)이어야합니다. PK는 고유 인덱스를 통해 적용되지만 클러스터 또는 비 클러스터 일 수 있습니다.
클러스터형 인덱스는 테이블의 데이터를 물리적으로 (즉, 디스크에) 정렬하는 수단이며 성능을 처리합니다. 데이터 무결성과는 아무런 관련이 없습니다. 클러스터형 인덱스 는키 열은 고유해야하며 (조합으로) 필요하지는 않습니다. 그러나 Clustered Index는 데이터의 물리적 순서이므로 각 행을 고유하게 식별해야합니다. 따라서 고유성을 요구하지 않도록 설정하면 숨겨진 4 바이트 "고유 자"열을 통해 고유 한 고유성을 생성합니다. 해당 열은 항상 고유하지 않은 클러스터형 인덱스에 있지만 키 필드가 고유 할 때 공간을 차지하지 않습니다 (조합). 이 "고유 화기"열의 작동 방식 (클러스터형 인덱스 및 비 클러스터형 인덱스에 미치는 영향)을 직접 확인하려면 PasteBin : T-SQL 스크립트 에 게시 한이 테스트 스크립트를 확인하십시오 .
따라서 다음의 주요 질문은
자동 증가 id
필드 를 추가하고 company_id
이를 기본 키 와 함께 사용하는 것이 더 효율적 이거나 불필요한 오버 헤드를 추가 하는가
이 두 개념을 혼동하고 있기 때문에 약간의 중복이 있지만 개별적으로 해결해야합니다.
IDENTITY
열을 추가 해야합니까 아니면 불필요한 오버 헤드가 필요합니까?
INT IDENTITY
컬럼 을 추가하고 이를 사용하여 PK를 작성하는 경우 클러스터 된 PK라고 가정하면 모든 행에 4 바이트가 추가됩니다. 이 열은 쿼리에서 볼 수 있고 사용할 수 있습니다. 그것은 할 수 있지만 발생하지 않습니다이 특정한 경우에, 외래 키로 다른 테이블에 추가 될 수있다.
INT IDENTITY
열을 추가하지 않으면 이 테이블에서 PK를 만들 수 없습니다. 그러나 UNIQUE
옵션을 사용하지 않는 한 테이블에 클러스터형 인덱스를 만들 수 있습니다 . 이 경우 SQL Server는 "uniquifier"라는 숨겨진 열을 추가하여 위에서 설명한대로 작동합니다. 열이 숨겨져 있으므로 쿼리 나 외래 키에 대한 참조로 사용할 수 없습니다.
효율성이 향상되는 한 이러한 옵션은 거의 동일합니다. 예, 일부 행 (초기 고유 키 값이있는 행)이 0 바이트를 차지하고 / PK의 모든 행 이 4 바이트를 차지하기 때문에 고유하지 않은 클러스터형 인덱스로 인해 차지하는 공간 이 약간 줄어 듭니다 IDENTITY
. 그러나 ID
쿼리 에서 열 을 사용할 수있는 편리함을 능가하지는 않지만 0 바이트 행 (특히 소량의 행이 예상 됨)이 차이를 알기에 충분하지 않습니다 .
INT IDENTITY 열 또는 org_path
지속 된 계산 열의 해시 ?
org_path
값을 기반으로 행을 찾지 않을 경우 Persisted Computed Column의 오버 헤드를 추가하고 Computed Column과 일치시키기 위해 쿼리에서 해시를 계산 해야하는 것이 합리적이지 않습니다. 여기 에서 개정 이력에서 사용할 수있는 최초 제안 ( 질문의 초기 문구 / 세부 사항을 기반으로 함). 이 경우 INT IDENTITY
"ID"열이 가장 적합합니다.
키 열 순서
점을 감안 ID
열이 거의 어느 경우 쿼리에서 사용하지됩니다 및 두 가지 주요 사용 사례 중 하나 "모든 행"또는 "주어진 모든 행을 얻을 수 있음을 주어 company_id
"나는에 PK를 만들 것입니다 company_id, id
. 이는 행이 순차적으로 삽입되지 않음을 의미하므로 FILLFACTOR
90을 지정합니다 . 조각화를 줄이려면 정기적 인 인덱스 유지 관리를 수행해야합니다.
두번째 질문
company_id가 다른 테이블의 기본 키라는 사실이 여기에 영향을 미칩니다.
아니.
방아쇠
org_path
내의 값 company_id
은 고유 하기 때문에 INSERT, UPDATE
이를 적용하려면 트리거를 작성해야 합니다. 트리거에서 IF EXISTS
a COUNT(*)
및 을 수행하는 쿼리를 사용하여을 수행하십시오 GROUP BY company_id, org_path
. 아무것도 발견되면 a ROLLBACK
를 발행 하여 DML 작업을 취소 한 다음 RAISERROR
중복이 있음을 알리십시오.
대조
내 초기 답변 (질문의 원래 문구 / 스파 스 세부 정보를 기반으로하고 여기 에서 개정 내역 에서 사용 가능)에서 이진 (즉 _BIN2
) 데이터 정렬을 사용하는 것이 좋습니다 . 이제 우리는 정확히 무엇에 대한 통찰력 가지고 org_path
입니다, 나는 것 없는 이진 데이터 정렬을 사용하는 것이 좋습니다. 분음 기호가있을 것입니다 때문에, 당신은 할 언어 적 동등성의 사용을 만들고 싶어.