GUID dường như là một lựa chọn tự nhiên cho khóa chính của bạn - và nếu bạn thực sự cần, có lẽ bạn có thể tranh luận để sử dụng nó cho KHÓA CHÍNH của bảng. Điều tôi khuyên bạn không nên làm là sử dụng cột GUID làm khóa phân cụm , mà SQL Server thực hiện theo mặc định, trừ khi bạn đặc biệt không nói với nó.
Bạn thực sự cần phải tách biệt hai vấn đề:
các khóa chính là một cấu trúc logic - một trong các phím ứng cử viên duy nhất và đáng tin cậy xác định mỗi hàng trong bảng. Đây có thể là bất cứ điều gì, thực sự - một INT
, một GUID
, một chuỗi - chọn những gì có ý nghĩa nhất cho kịch bản của bạn.
các chìa khóa phân nhóm (cột hoặc cột mà xác định "nhóm chỉ số" trên bảng) - đây là một chất điều lưu trữ liên quan đến, và ở đây, một nhỏ, ổn định, ngày càng tăng kiểu dữ liệu là lựa chọn tốt nhất của bạn - INT
hoặc BIGINT
là bạn tùy chọn mặc định.
Theo mặc định, khóa chính trên bảng SQL Server cũng được sử dụng làm khóa phân cụm - nhưng điều đó không cần phải như vậy! Cá nhân tôi đã thấy hiệu suất tăng đáng kể khi chia khóa Chính / cụm được dựa trên GUID trước đó thành hai khóa riêng biệt - khóa chính (logic) trên GUID và khóa phân cụm (đặt hàng) trên một INT IDENTITY(1,1)
cột riêng .
Như Kimberly Tripp - Nữ hoàng lập chỉ mục - và những người khác đã tuyên bố rất nhiều lần - GUID
vì khóa phân cụm không tối ưu, do tính ngẫu nhiên của nó, nó sẽ dẫn đến phân mảnh trang và chỉ mục lớn và hiệu suất nói chung rất tệ.
Vâng, tôi biết - có newsequentialid()
trong SQL Server 2005 trở lên - nhưng ngay cả điều đó không thực sự và đầy đủ theo trình tự và do đó cũng bị các vấn đề tương tự như GUID
- chỉ kém một chút nổi bật như vậy.
Sau đó, có một vấn đề khác cần xem xét: khóa phân cụm trên bảng sẽ được thêm vào từng mục nhập trên mỗi và mọi chỉ mục không phân cụm trên bảng của bạn - do đó bạn thực sự muốn đảm bảo rằng nó càng nhỏ càng tốt. Thông thường, một hơn INT
2 tỷ hàng sẽ đủ cho phần lớn các bảng - và so với GUID
khóa phân cụm, bạn có thể tiết kiệm cho mình hàng trăm megabyte dung lượng lưu trữ trên đĩa và trong bộ nhớ máy chủ.
Tính toán nhanh - sử dụng INT
so với GUID
khóa chính và cụm:
- Bảng cơ sở với 1000'000 hàng (3,8 MB so với 15,26 MB)
- 6 chỉ mục không bao gồm (22,89 MB so với 91,55 MB)
TỔNG: 25 MB so với 106 MB - và đó chỉ là trên một bảng duy nhất!
Một số thực phẩm khác cho suy nghĩ - công cụ tuyệt vời của Kimberly Tripp - đọc nó, đọc lại, tiêu hóa nó! Đó là phúc âm lập chỉ mục SQL Server, thực sự.
Tái bút: tất nhiên, nếu bạn đang giải quyết chỉ vài trăm hoặc vài nghìn hàng - hầu hết các đối số này sẽ không thực sự ảnh hưởng đến bạn. Tuy nhiên: nếu bạn nhận được hàng chục hoặc hàng trăm ngàn hàng hoặc bạn bắt đầu đếm hàng triệu - thì những điểm đó trở nên rất quan trọng và rất quan trọng để hiểu.
Cập nhật: nếu bạn muốn có PKGUID
cột của mình làm khóa chính (nhưng không phải là khóa phân cụm của bạn) và một cột khác MYINT
( INT IDENTITY
) làm khóa phân cụm của bạn - hãy sử dụng:
CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
MyINT INT IDENTITY(1,1) NOT NULL,
.... add more columns as needed ...... )
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)
CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
Về cơ bản: bạn chỉ cần nói rõ ràng ràngPRIMARY KEY
buộc rằng nó NONCLUSTERED
(nếu không nó được tạo như là chỉ mục được nhóm của bạn, theo mặc định) - và sau đó bạn tạo một chỉ mục thứ hai được xác định làCLUSTERED
Điều này sẽ hoạt động - và đó là một tùy chọn hợp lệ nếu bạn có một hệ thống hiện tại cần được "thiết kế lại" để thực hiện. Đối với một hệ thống mới, nếu bạn bắt đầu từ đầu và bạn không ở trong một kịch bản sao chép, thì tôi luôn chọn ID INT IDENTITY(1,1)
khóa chính của mình - hiệu quả hơn bất kỳ thứ gì khác!