Một điều cần xem xét là Khóa chính và Chỉ mục cụm không giống nhau. Khóa chính là một ràng buộc và liên quan đến các quy tắc mà dữ liệu tồn tại (tức là toàn vẹn dữ liệu); nó không có gì để làm với hiệu quả / hiệu suất. Khóa chính yêu cầu (các) cột khóa phải là duy nhất (kết hợp) và KHÔNG NULL (riêng lẻ). Một PK được thi hành thông qua một Chỉ mục duy nhất, mặc dù nó có thể được phân cụm hoặc không phân cụm.
Chỉ mục cụm là một phương tiện vật lý (tức là trên đĩa) sắp xếp dữ liệu trong bảng và xử lý hiệu suất; nó không có gì để làm với tính toàn vẹn dữ liệu. Một chỉ số cụm có thểyêu cầu (các) cột khóa là duy nhất (kết hợp), nhưng nó không cần. Tuy nhiên, vì Chỉ mục cụm là thứ tự vật lý của dữ liệu, nên nó cần xác định duy nhất mỗi hàng bất kể là gì. Vì vậy, nếu bạn không đặt nó để yêu cầu tính duy nhất, nó sẽ tạo ra tính duy nhất của riêng nó thông qua cột "uniquifier" 4 byte ẩn. Cột đó luôn có trong các Chỉ mục cụm không duy nhất, nhưng nó không chiếm bất kỳ khoảng trống nào khi các trường khóa là duy nhất (kết hợp). Để xem tận mắt cột "uniquifier" này hoạt động như thế nào (cả trong Chỉ mục cụm và hiệu ứng trên Chỉ mục không phân cụm), vui lòng kiểm tra tập lệnh kiểm tra này tôi đã đăng trên tập lệnh PasteBin: T-SQL để kiểm tra kích thước của Trình duy nhất .
Do đó, câu hỏi chính của:
nó sẽ hiệu quả hơn để thêm tự động tăng id
trường và sử dụng trường đó company_id
làm khóa chính hoặc thêm chi phí không cần thiết
đang kết hợp hai khái niệm đó, vì vậy chúng cần được giải quyết một cách riêng biệt, mặc dù chắc chắn có một số chồng chéo.
Nên một IDENTITY
cột nên được thêm vào hoặc nó sẽ là chi phí không cần thiết?
Nếu bạn thêm một INT IDENTITY
cột và sử dụng nó để tạo PK, giả sử đó sẽ là PK cụm, có thêm 4 byte cho mỗi hàng. Cột này có thể nhìn thấy và có thể sử dụng trong các truy vấn. Nó có thể được thêm vào các bảng khác dưới dạng Khóa ngoài, mặc dù trong trường hợp cụ thể này sẽ không xảy ra.
Nếu bạn không thêm INT IDENTITY
cột, thì bạn không thể tạo PK trên bảng này. Tuy nhiên, bạn vẫn có thể tạo Chỉ mục cụm trên bảng miễn là bạn không sử dụng UNIQUE
tùy chọn. Trong trường hợp này, SQL Server sẽ thêm một cột ẩn gọi là "uniquifier" hoạt động như mô tả ở trên. Vì cột bị ẩn, nó không thể được sử dụng trong các truy vấn hoặc làm tài liệu tham khảo cho Khóa ngoại.
Về hiệu quả, các tùy chọn này gần như giống nhau. Có, sẽ có ít không gian hơn một chút khi có Chỉ số cụm không duy nhất do một số hàng (những hàng có giá trị khóa duy nhất ban đầu) chiếm 0 byte trong khi tất cả các hàng trong IDENTITY
/ PK sẽ lấy 4 byte. Nhưng sẽ không có đủ các hàng 0 byte (đặc biệt là với số lượng hàng nhỏ dự kiến) sẽ nhận thấy sự khác biệt, chứ đừng nói đến việc cân nhắc sự tiện lợi của việc có thể sử dụngID
cột trong các truy vấn.
Cột INTENTENT hoặc Hash của org_path
cột được tính toán bền vững?
Vì bạn sẽ không tìm kiếm các hàng dựa trên org_path
các giá trị, nên sẽ không có ý nghĩa gì khi thêm chi phí của Cột được tính toán liên tục cộng với việc cần tính toán hàm băm đó trong các truy vấn để khớp với Cột được tính (đây là của tôi đề xuất ban đầu, có sẵn trong lịch sử sửa đổi ở đây , dựa trên từ ngữ / chi tiết ban đầu của Câu hỏi). Trong trường hợp cụ thể này, INT IDENTITY
Cột "ID" có lẽ là tốt nhất.
Thứ tự cột chính
Cho rằng ID
Cột sẽ hiếm khi được sử dụng trong các truy vấn và cho rằng hai trường hợp sử dụng chính là lấy "tất cả các hàng" hoặc "tất cả các hàng cho một company_id
" nhất định , tôi sẽ tạo PK trên company_id, id
. Và bởi vì điều này có nghĩa là các hàng không được chèn liên tục, tôi sẽ chỉ định một FILLFACTOR
trong 90. Bạn cũng sẽ cần đảm bảo duy trì chỉ số thường xuyên để giảm phân mảnh.
Câu hỏi thứ hai
thực tế rằng company_id là khóa chính trong một bảng khác có ảnh hưởng gì ở đây không
Không.
Kích hoạt
Vì org_path
các giá trị trong một company_id
là duy nhất, bạn vẫn nên tạo Kích hoạt INSERT, UPDATE
để thực thi điều này. Trong Kích hoạt, thực hiện IF EXISTS
một truy vấn có thể thực hiện một COUNT(*)
và GROUP BY company_id, org_path
. Nếu tìm thấy bất cứ điều gì, hãy đưa ra yêu ROLLBACK
cầu hủy bỏ hoạt động DML và sau đó RAISERROR
nói rằng có các bản sao.
Đối chiếu
Trong câu trả lời ban đầu của tôi (dựa trên từ ngữ gốc / chi tiết thưa thớt của câu hỏi và có sẵn trong lịch sử sửa đổi ở đây ), tôi đã đề xuất có thể sử dụng Đối chiếu nhị phân (tức là _BIN2
). Bây giờ chúng tôi có cái nhìn sâu sắc về chính xác org_path
là gì , tôi không khuyên bạn nên sử dụng Collation nhị phân. Vì sẽ có dấu phụ, bạn không muốn sử dụng các tương đương ngôn ngữ.