Có, hoàn toàn có những hậu quả tiêu cực đối với việc sử dụng một chuỗi thay vì kiểu số cho Khóa chính và thậm chí còn nhiều hơn nếu PK đó được phân cụm (mà thực sự là trong trường hợp của bạn). Tuy nhiên, mức độ bạn thấy (các) hiệu ứng của việc sử dụng trường chuỗi là một hàm của a) có bao nhiêu hàng trong bảng này và b) có bao nhiêu hàng trong các bảng khác được Khóa ngoài cho PK này. Nếu bạn chỉ có 10k hàng trong bảng này và 100k hàng trong một vài bảng khác FK đến bảng này qua trường đó, thì có lẽ nó sẽ không được chú ý. Nhưng những hiệu ứng đó chắc chắn trở nên đáng chú ý hơn khi số lượng hàng tăng lên.
Bạn cần xem xét rằng các trường trong Chỉ mục được nhóm được chuyển sang Chỉ mục không được nhóm. Vì vậy, bạn không chỉ nhìn vào tối đa 40 byte mỗi hàng, mà là (40 * some_number) byte. Và trong bất kỳ bảng FK nào, bạn có cùng 40 byte trong hàng cộng với thường xuyên hơn sẽ không có chỉ mục Không phân cụm trên trường đó vì nó đang được sử dụng trong THAM GIA, vì vậy giờ đây nó thực sự được nhân đôi trong bất kỳ bảng nào mà FK cái này. Nếu một người có xu hướng nghĩ rằng 40 byte * 1 triệu hàng * 10 bản sao thì không có gì phải lo lắng, vui lòng xem bài viết của tôi Disk Is Cheap! ORLY? trong đó nêu chi tiết tất cả (hoặc ít nhất là hầu hết) các khu vực bị ảnh hưởng bởi quyết định này.
Một điều khác cần xem xét là việc lọc và sắp xếp các chuỗi, đặc biệt là khi không sử dụng Collation nhị phân (tôi giả sử bạn đang sử dụng mặc định cơ sở dữ liệu thường không phân biệt chữ hoa chữ thường) sẽ kém hiệu quả hơn (tức là mất nhiều thời gian hơn) so với khi sử dụng INT
/ BIGINT
. Điều này tác động đến tất cả các truy vấn lọc / tham gia / sắp xếp trên trường này.
Do đó, sử dụng một cái gì đó như thế CHAR(5)
có lẽ sẽ ổn cho PK cụm, nhưng chủ yếu là nếu nó cũng được xác định bằng COLLATE Latin1_General_100_BIN2
(hoặc một cái gì đó tương tự).
Và giá trị của [CODE]
bao giờ có thể thay đổi? Nếu có thì đó là lý do thậm chí nhiều hơn để không sử dụng nó như một PK (ngay cả khi bạn đặt FK thành ON UPDATE CASCADE
). Nếu nó không thể hoặc sẽ không bao giờ thay đổi thì tốt, nhưng vẫn còn quá nhiều lý do để không sử dụng nó làm PK cụm.
Tất nhiên, câu hỏi có thể được đặt ra không chính xác vì có vẻ như bạn hiện đã có trường này trong PK của mình.
Bất kể, tùy chọn tốt nhất của bạn, cho đến nay, là sử dụng [ID_CODE]
như PK cụm, sử dụng trường đó trong các bảng có liên quan làm FK và giữ [CODE]
dưới dạng UNIQUE INDEX
(có nghĩa là "khóa thay thế").
Cập nhật thêm
một chút thông tin dựa trên câu hỏi này trong một bình luận về câu trả lời này:
Có phải [ID_CODE], là PRIMARY KEY, tùy chọn tốt nhất nếu tôi sử dụng cột [CODE] để tra cứu bảng không?
Tất cả điều này phụ thuộc vào rất nhiều yếu tố, một số trong đó tôi đã đề cập nhưng sẽ trình bày lại:
Khóa chính là cách xác định hàng riêng lẻ, cho dù nó có được tham chiếu bởi bất kỳ Khóa ngoại nào hay không. Cách hệ thống của bạn xác định nội bộ hàng có liên quan đến, nhưng không nhất thiết giống như cách người dùng của bạn xác định hàng / hàng đó. Bất kỳ cột KHÔNG NULL nào có dữ liệu duy nhất đều có thể hoạt động, nhưng có những vấn đề thực tế cần xem xét, đặc biệt là nếu trên thực tế, PK được tham chiếu bởi bất kỳ FK nào. Ví dụ, GUID là duy nhất và một số người thực sự thích sử dụng chúng vì nhiều lý do, nhưng chúng khá tệ đối với Chỉ mục cụm ( NEWSEQUENTIALID
tốt hơn, nhưng không hoàn hảo). Mặt khác, GUID chỉ hoạt động tốt như các phím thay thế và được ứng dụng sử dụng để tra cứu hàng, nhưng THAM GIA vẫn được thực hiện bằng cách sử dụng PK INT (hoặc tương tự).
Cho đến nay bạn chưa nói với chúng tôi cách [CODE]
trường phù hợp với hệ thống từ mọi góc độ, ngoài bây giờ đề cập rằng đây là cách bạn tìm kiếm các hàng, nhưng đó có phải là cho tất cả các truy vấn hay chỉ một số? Vì thế:
Về [CODE]
giá trị:
- Nó được tạo ra như thế nào?
- Là tăng dần hay psuedo-ngẫu nhiên?
- Là chiều dài đồng đều hoặc chiều dài khác nhau?
- Những nhân vật được sử dụng?
- Nếu sử dụng các ký tự chữ cái: nó là trường hợp nhạy cảm hoặc không nhạy cảm?
- Nó có thể thay đổi sau khi được chèn không?
Về bảng này:
- Có bảng nào khác FK cho bảng này không? Hoặc các trường này (
[CODE]
hoặc [ID_CODE]
) được sử dụng trong các bảng khác, ngay cả khi không rõ ràng là Khóa ngoài?
- Nếu
[CODE]
là trường duy nhất được sử dụng để có được các hàng riêng lẻ thì [ID_CODE]
trường phục vụ cho mục đích gì? Nếu nó không được sử dụng, tại sao lại có nó ở vị trí đầu tiên (có thể phụ thuộc vào câu trả lời cho "Trường có thể [CODE]
thay đổi không?")?
- Có bao nhiêu hàng trong bảng này?
- Nếu các bảng khác để tham chiếu bảng này, có bao nhiêu và bao nhiêu hàng trong mỗi bảng?
- Các chỉ số cho bảng này là gì?
Quyết định này không thể được đưa ra hoàn toàn cho câu hỏi "NVARCHAR có hay không?". Tôi một lần nữa sẽ nói rằng nói chung tôi không thấy đó là một ý tưởng tốt, nhưng chắc chắn sẽ có lúc nó ổn. Với rất ít trường trong bảng này, không có khả năng có thêm hoặc ít nhất là không có nhiều chỉ mục. Vì vậy, bạn có thể ổn cả hai cách để có [CODE]
được Chỉ số cụm. Và nếu không có bảng nào khác tham chiếu bảng này thì bạn cũng có thể biến nó thành PK. Nhưng, nếu các bảng khác tham chiếu bảng này thì tôi sẽ chọn [ID_CODE]
trường là PK, ngay cả khi Không phân cụm.