Tôi có bảng người dùng với userid
và username
và cả hai đều là duy nhất. Giữa userid
và username
, tốt hơn nên sử dụng làm khóa ngoại và tại sao? Boss của tôi muốn sử dụng chuỗi? Ổn chứ?Chuỗi hoặc int được ưu tiên cho khóa ngoài?
Trả lời
Dường như bạn có cả một phím thay thế (int userId
) và một chìa khóa tự nhiên (char
hoặc varchar username
). Một trong hai cột có thể được sử dụng như là một khóa chính cho bảng, và một trong hai cách, bạn sẽ vẫn có thể thực thi tính duy nhất của khóa khác.
Có nhiều cuộc thảo luận hiện có về sự cân bằng giữa Khóa tự nhiên và thay thế - bạn sẽ cần phải quyết định điều gì phù hợp với bạn và 'chuẩn' nằm trong tổ chức của bạn.
Dưới đây là một số lưu ý khi lựa chọn cách này hay cách khác:
Trường hợp cho việc sử dụng Surrogate phím (ví dụ UserId INT AUTO_INCREMENT)
Nếu bạn sử dụng một UserId (ví dụ AUTO_INCREMENT INT) là Primary Khóa, khi đó tất cả các bảng tham chiếu bảng MyUsers
sẽ sử dụng UserId
làm Khóa ngoại.
Bạn vẫn có thể tuy nhiên thực thi độc đáo của cột varchar username
qua sử dụng thêm một unique index, ví dụ:
CREATE TABLE `MyUsers` (
`userId` int NOT NULL AUTO_INCREMENT,
`username` varchar(100) NOT NULL,
... other columns
PRIMARY KEY(`userId`),
UNIQUE KEY UQ_UserName (`username`)
Theo @Dagon, sử dụng một khóa chính hẹp (như một int
) có hiệu suất và lưu trữ những lợi ích sử dụng giá trị rộng hơn (và độ dài biến đổi) như varchar
. Lợi ích này cũng ảnh hưởng đến các bảng khác có tham chiếu MyUsers
, vì khóa ngoài là userid
sẽ hẹp hơn.
Ngoài ra, nếu tất cả các bảng được ghép với MyUsers
qua username
, việc thay đổi tên người dùng trở nên bất tiện hơn (vì mối quan hệ khóa ngoại vi sẽ bị vi phạm). Nếu cần cập nhật tên người dùng trên các bảng sử dụng username
làm khóa ngoại, thì cần phải sử dụng kỹ thuật như ON UPDATE CASCADE để duy trì tính toàn vẹn của dữ liệu.
Tuy nhiên, với khóa số nguyên thay thế, tên người dùng có thể được thay đổi mà không ảnh hưởng đến các bảng tham chiếu MyUsers
(nhưng thay đổi vẫn có thể theo dõi).
Trường hợp cho việc sử dụng phím tự nhiên (ví dụ: tên người dùng)
Về phía xuống cho việc sử dụng Surrogate Keys, bảng tham khảo MyUsers
qua một phím thay thế sẽ luôn yêu cầu một tham gia trở lại bảng để lấy tên người dùng. Một trong những lợi ích tiềm năng của khóa Tự nhiên là nếu truy vấn chỉ yêu cầu cột Username
từ bảng tham chiếu MyUsers
, thì không cần phải tham gia lại MyUsers
để truy xuất tên người dùng. Trong một ý nghĩa, các khóa tự nhiên cung cấp một hình thức nhẹ của bộ đệm ẩn trên cột khóa.
+1 cho một câu trả lời thực dụng, cả hai giải pháp đều có tính chuyên nghiệp và khuyết điểm của họ. Cá nhân, tôi thích giải pháp Key Surrogate hơn. –
404 trên liên kết cuối cùng được cung cấp. – johnsnails
int sẽ index nhanh hơn, có thể hoặc không là một vấn đề, khó có thể nói dựa trên những gì bạn đã cung cấp
Một int là 4 byte, một chuỗi có thể được như nhiều byte như bạn muốn. Do đó, một int sẽ luôn hoạt động tốt hơn. Trừ khi ofcourse nếu bạn gắn bó với tên người dùng có ít hơn 4 ký tự dài :)
Bên cạnh đó, bạn không bao giờ nên sử dụng cột là PK/FK nếu dữ liệu bên trong cột có thể thay đổi. Người dùng có xu hướng thay đổi tên người dùng của họ và ngay cả khi chức năng đó không tồn tại trong ứng dụng của bạn ngay bây giờ, hãy tạm dừng nó trong vài năm tới. Khi ngày đó đến, bạn có thể có 1000 bảng tham chiếu đến bảng người dùng đó, và sau đó bạn sẽ phải cập nhật tất cả 1000 bảng trong một giao dịch và điều đó thật tệ.
không phải là "cập nhật cascade" tài sản của khóa nước ngoài có để chăm sóc các tình huống như vậy? Hay tôi đang thiếu một cái gì đó? Tôi đồng ý với điểm 4 byte/4 ký tự. Nhưng tôi không đồng ý với đối số thứ hai. – shantanuo
Chắc chắn, bạn có thể làm điều đó, nhưng nó vẫn còn xấu. Cập nhật đó có thể mất nhiều thời gian hơn và tạo nhiều khóa hơn mức chấp nhận được. Nhưng nếu đó không phải là vấn đề đối với ứng dụng cụ thể, hãy tiếp tục. Tôi vẫn không khuyên bạn nên nó mặc dù. – TheQ
Tôi có thể hỏi tại sao bạn có hai cột duy nhất trong bảng? –
Tại sao anh ta không thể có hai cột duy nhất. Giống như có ID, email và tên người dùng. Họ có thể là tất cả duy nhất, phải không? –
Tôi thừa nhận. Câu hỏi ngớ ngẩn. Chỉ cần tự hỏi nếu hai cột đã thực sự mô tả cùng một điều. nonnb trả lời câu hỏi một cách đáng thương. –