그렇습니다. 기본 키에 숫자 유형 대신 문자열을 사용하면 부정적인 결과가 발생하며 PK가 클러스터 된 경우 (실제로 귀하의 경우) 더욱 그렇습니다. 그러나 문자열 필드를 사용하는 효과는 a)이 테이블에있는 행 수 및 b)이 테이블에 외래 키가 지정된 다른 테이블의 행 수의 함수입니다. 이 테이블에 10k 개의 행만 있고 해당 필드를 통해이 테이블에 FK되는 다른 몇 개의 테이블에 100k 개의 행만있는 경우 그렇게 눈에 띄지 않을 수 있습니다. 그러나 행 개수가 증가함에 따라 이러한 효과가 더욱 두드러집니다.
클러스터형 인덱스의 필드가 비 클러스터형 인덱스로 이월되는 것을 고려해야합니다. 따라서 행 당 최대 40 바이트를 보는 것이 아니라 (40 * some_number) 바이트입니다. 그리고 모든 FK 테이블에서 행에 동일한 40 바이트가 있고 JOIN에서 사용되는 것처럼 해당 필드에 비 클러스터형 인덱스가있는 것보다 자주 발생하므로 이제 FK 테이블에서 두 배가됩니다. 이 하나. 40 바이트 * 1 백만 행 * 10 복사본에 대해 걱정할 필요가 없다면 내 기사 Disk is Cheap! 를 참조하십시오 . 오랄? 이 결정에 영향을받는 모든 영역 (또는 최소한)을 자세히 설명합니다.
고려해야 할 또 다른 사항은 문자열 필터링 및 정렬, 특히 이진 데이터 정렬을 사용하지 않는 경우 (대개 대소 문자를 구분하지 않는 데이터베이스 기본값을 사용한다고 가정)는 INT
/를 사용할 때보 다 훨씬 덜 효율적입니다 (즉, 시간이 더 오래 걸림) BIGINT
. 이는이 필드에서 필터링 / 결합 / 정렬하는 모든 쿼리에 영향을줍니다.
따라서 CHAR(5)
Clustered PK에는 이와 비슷한 것을 사용하는 것이 좋을 수도 있지만 대부분이 PK로 정의 된 경우 COLLATE Latin1_General_100_BIN2
(또는 이와 유사한 것) 가능합니다.
그리고 [CODE]
이제까지 의 가치 가 변할 수 있습니까? 그렇다면 PK로 사용하지 않는 것이 더 많은 이유입니다 (FK를로 설정하더라도 ON UPDATE CASCADE
). 변경할 수 없거나 변경되지 않는 경우에도 클러스터 PK로 사용하지 않는 충분한 이유가 있습니다.
물론 현재 PK에이 필드가 이미있는 것 같으므로 질문이 잘못 표현되었을 수 있습니다.
에 관계없이, 당신의 최선의 선택은, 지금까지 사용하는 것입니다 [ID_CODE]
FK 같은 관련 테이블의 필드, 그리고 유지하는 것이, 클러스터 된 PK로 사용을 [CODE]
A와 UNIQUE INDEX
(그것이 "대체 키"입니다 의미).
이 답변에 대한 의견 에서이 질문에 대한 좀 더 많은 정보를 업데이트하십시오 :
[CODE] 열을 사용하여 테이블을 조회하는 경우 [ID_CODE]가 PRIMARY KEY로서 가장 좋은 옵션입니까?
이 모든 것은 매우 많은 요소에 달려 있으며, 그중 일부는 이미 언급했지만 다시 언급 할 것입니다.
기본 키는 외래 키에 의해 참조되는지 여부에 관계없이 개별 행을 식별하는 방법입니다. 시스템이 행을 내부적으로 식별하는 방법은 사용자가 자신을 식별하는 방법과 반드시 동일하지는 않습니다. 고유 한 데이터 가있는 NOT NULL 열 은 작동 할 수 있지만 특히 PK가 실제로 FK에 의해 참조되는 경우 고려해야 할 실질적인 문제가 있습니다. 예를 들어 GUID는 독특하고 일부 사람들은 여러 가지 이유로 GUID를 사용하는 것을 정말로 좋아하지만 클러스터형 인덱스에는 좋지 NEWSEQUENTIALID
않습니다 ( 더 좋지만 완벽하지는 않습니다). 반면 GUID는 대체 키처럼 훌륭하고 행을 조회하는 데 앱에서 사용되지만 JOIN은 여전히 INT (또는 유사한) PK를 사용하여 수행됩니다.
지금까지는 [CODE]
필드가 모든 각도에서 시스템에 어떻게 적용되는지 알려주지 않았습니다. 지금은 이것이 행을 찾는 방법이지만 모든 쿼리 또는 일부에 대한 것입니까? 그 후:
[CODE]
값 과 관련하여 :
- 어떻게 생성됩니까?
- 증분 또는 의사 랜덤입니까?
- 길이가 균일합니까 아니면 길이가 변합니까?
- 어떤 문자가 사용됩니까?
- 알파벳 문자를 사용하는 경우 : 대소 문자를 구분합니까?
- 삽입 한 후에도 바꿀 수 있습니까?
이 테이블과 관련하여 :
- 이 테이블에 다른 테이블이 있습니까? 또는 명시 적으로 외래 키가 아니더라도 이러한 필드 (
[CODE]
또는 [ID_CODE]
)가 다른 테이블에서 사용됩니까?
- 경우
[CODE]
유일한 필드는 개별 행을 가져 오는 데 사용됩니다, 다음, 어떤 목적 않는 [ID_CODE]
필드 봉사? 그것이 사용되지 않는다면, 왜 처음에 그것을 가지고 [CODE]
있습니까?
- 이 테이블에 몇 개의 행이 있습니까?
- 다른 테이블이이 테이블을 참조 할 경우 각 테이블에 몇 개의 행이 있습니까?
- 이 테이블의 인덱스는 무엇입니까?
이 결정은 순전히 "NVARCHAR 예 또는 아니오?"에 관한 질문으로 이루어질 수 없습니다. 다시 말하지만 일반적으로 말하면 그것이 좋은 생각이라고 생각하지는 않지만 확실히 괜찮을 때가 있습니다. 이 테이블에 필드가 너무 적 으면 더 이상 또는 적어도 많은 인덱스가 없을 것입니다. 따라서 [CODE]
클러스터형 인덱스로 사용하는 것이 좋습니다. 그리고 다른 테이블이이 테이블을 참조하지 않으면 PK로 만들 수도 있습니다. 그러나 다른 테이블이이 테이블을 참조하는 [ID_CODE]
경우 비 클러스터형이라도 필드를 PK로 선택합니다 .