Tại sao lại sử dụng nhiều cột làm khóa chính (khóa chính tổng hợp)


109

Ví dụ này được lấy từ w3schools .

CREATE TABLE Persons
(
    P_Id int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255),
    CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)

Sự hiểu biết của tôi là cả hai cột cùng nhau ( P_IdLastName) đại diện cho một khóa chính cho bảng Persons. Điều này có chính xác?

  • Tại sao ai đó muốn sử dụng nhiều cột làm khóa chính thay vì một cột duy nhất?
  • Có bao nhiêu cột có thể được sử dụng cùng nhau làm khóa chính trong một bảng nhất định?

... bây giờ đó cũng là một câu trả lời cho câu hỏi 2'nd
Wolf

1
@Martijn Peters. Tại sao Câu trả lời bị xóa?
PerformanceDBA

Câu trả lời:


119

Sự am hiểu của bạn đa đung đăn.

Bạn sẽ làm điều này trong nhiều trường hợp. Một ví dụ là trong mối quan hệ như OrderHeaderOrderDetail. PK trong OrderHeadercó thể là OrderNumber. PK trong OrderDetailcó thể là OrderNumberAND LineNumber. Nếu nó là một trong hai cái đó, nó sẽ không phải là duy nhất, nhưng sự kết hợp của cả hai được đảm bảo là duy nhất.

Cách thay thế là sử dụng khóa chính (không thông minh) được tạo, chẳng hạn trong trường hợp này OrderDetailId. Nhưng không phải lúc nào bạn cũng thấy mối quan hệ dễ dàng như vậy. Một số người thích một cách; một số thích cách khác.


2
Điều này có hữu ích không nếu tôi đang sử dụng branch_id và sử dụng sao chép giữa hai cơ sở dữ liệu, sẽ giải quyết được trùng lặp id? !!
Mhmd

11
Lưu ý rằng trong nhiều trường hợp sử dụng khóa chính đã tạo, bạn thường vẫn muốn có một khóa duy nhất trên các giá trị tổng hợp.
Bacon Bits,

Vui lòng giải thích thêm về "Một số người thích một cách; một số người thích cách khác".
Tên người dùng

1
Cầu xin công phu? Không biết phải nói gì. Tôi đã biết những người thích có nhiều trường nối nhau làm khóa vì dễ dàng hiểu những gì họ đang xem bằng trực giác hơn. Tôi đã biết những người khác chỉ thích chỉ định một khóa duy nhất cho mỗi hàng vì nó dễ dàng hơn và nhanh hơn để nhập. đó có phải là điều mà bạn đang hỏi?
MJB

Thông báo đó dành cho @Username. Tôi quên chỉ đạo nó.
MJB

26

Một ví dụ khác về khóa chính ghép là việc sử dụng các bảng Hiệp hội. Giả sử bạn có một bảng người chứa một nhóm người và một bảng nhóm chứa một nhóm nhóm. Bây giờ bạn muốn tạo mối quan hệ nhiều đến nhiều người và nhóm. Có nghĩa là mỗi người có thể thuộc nhiều nhóm. Đây là cấu trúc bảng sẽ trông như thế nào khi sử dụng khóa chính ghép.

Create Table Person(
PersonID int Not Null,
FirstName varchar(50),
LastName varchar(50),
Constraint PK_Person PRIMARY KEY (PersonID))

Create Table Group (
GroupId int Not Null,
GroupName varchar(50),
Constraint PK_Group PRIMARY KEY (GroupId))

Create Table GroupMember (
GroupId int Not Null,
PersonId int Not Null,
CONSTRAINT FK_GroupMember_Group FOREIGN KEY (GroupId) References Group(GroupId),
CONSTRAINT FK_GroupMember_Person FOREIGN KEY (PersonId) References Person(PersonId),
CONSTRAINT PK_GroupMember PRIMARY KEY (GroupId, PersonID))

giải thích tuyệt vời: Tôi nghĩ rằng sự cần thiết của các thuộc tính cho các quan hệ m-to-n (trong một giao thức chuẩn hóa) là chìa khóa.
Wolf,

có thể thêm một chút giải thích về lợi ích sẽ tốt hơn
Martian2049

10

Ví dụ của W3Schools không cho biết khi nào bạn nên sử dụng khóa chính ghép và chỉ đưa ra cú pháp ví dụ bằng cách sử dụng cùng một bảng ví dụ như cho các khóa khác.

Sự lựa chọn ví dụ của họ có thể gây hiểu lầm cho bạn khi kết hợp một khóa vô nghĩa (P_Id) và một khóa tự nhiên (LastName). Lựa chọn khóa chính kỳ lạ này nói rằng các hàng sau đây hợp lệ theo lược đồ và cần thiết để xác định duy nhất một học sinh. Trực giác điều này không có ý nghĩa.

1234     Jobs
1234     Gates

Đọc thêm: Cuộc tranh luận về khóa chính tuyệt vời hoặc chỉ Google meaningless primary keyshoặc thậm chí đọc kỹ câu hỏi SO này

FWIW - 2 xu của tôi là để tránh khóa chính nhiều cột và sử dụng trường id được tạo duy nhất (khóa thay thế) làm khóa chính và thêm các ràng buộc bổ sung (duy nhất) nếu cần.


1
1) liên kết "cuộc tranh luận về khóa chính tuyệt vời" đặc biệt ngu ngốc, thông tin tự phục vụ và sai. 2) Không thể tránh được chỉ mục trên các cột tạo nên hàng duy nhất. ID "đại diện" có chỉ mục luôn là cột bổ sung và chỉ mục bổ sung. Đúng hơn là ngớ ngẩn vì nó là thừa. Và chậm hơn.
PerformanceDBA

2
"Cuộc tranh luận về khóa chính tuyệt vời" không phải là ngu ngốc. Đó là một vấn đề rất hợp lệ từ các nhà phát triển không phải là nhà phát triển sql hoặc sql DBA và không dành toàn bộ thời gian cho sql. Ngay cả trong sql thuần túy, tôi thà có một khóa được tạo tự động vô nghĩa làm khóa chính khi tham gia hơn là phải nhớ chuyển n bit dữ liệu xung quanh là khóa tự nhiên. Bạn hoan nghênh quan điểm của mình, nhưng chúng tôi đánh giá cao việc không quá bác bỏ.
Robert Paulson

4

Bạn sử dụng khóa ghép (khóa có nhiều thuộc tính) bất cứ khi nào bạn muốn đảm bảo tính duy nhất của sự kết hợp nhiều thuộc tính. Một khóa thuộc tính duy nhất sẽ không đạt được điều tương tự.


1
Đối với việc đảm bảo một khóa duy nhất, bạn có thể dựa vào sự kết hợp của hai thuộc tính để tạo thành một khóa không thể trùng lặp một cách hợp lý, Người và ngày tốt nghiệp từ một tập dữ liệu lớn hơn sẽ là một ví dụ.
John Mark

3

Có, cả hai đều tạo thành khóa chính. Đặc biệt trong các bảng mà bạn không có khóa thay thế , có thể cần phải chỉ định nhiều thuộc tính làm mã định danh duy nhất cho mỗi bản ghi (ví dụ xấu: bảng có cả tên và họ có thể yêu cầu kết hợp chúng thành độc nhất).


3

Nói chung, nhiều cột trong một khóa sẽ hoạt động kém hơn một khóa thay thế. Tôi thích có một khóa thay thế và sau đó là một chỉ mục duy nhất trên một khóa đa cột. Bằng cách đó, bạn có thể có hiệu suất tốt hơn và tính duy nhất cần thiết được duy trì. Và tốt hơn nữa, khi một trong các giá trị trong khóa đó thay đổi, bạn cũng không phải cập nhật một triệu mục nhập con trong 215 bảng con.


1
1) Hiệu suất. Không phải trong nền tảng SQL (có thể là "sql" và phần mềm miễn phí). 2) Sở thích là không liên quan. Những gì các bảng yêu cầu, đối với tính toàn vẹn, có liên quan. 3) ID "đại diện" có chỉ mục luôn là cột bổ sung và chỉ mục bổ sung . Vì vậy, điều đó sẽ chậm hơn, trên bất kỳ nền tảng nào. Lại hiệu suất, bạn mâu thuẫn với chính mình. 4) Nếu bạn không biết cách cập nhật "triệu mục con trong 215 bảng con" thần thoại đúng cách , hãy đặt câu hỏi.
PerformanceDBA

2
Tôi không đồng ý với tuyên bố 'Nói chung, nhiều cột trong một khóa sẽ hoạt động kém hơn một khóa thay thế'. Thường thì cần thêm một truy vấn để lấy khóa đại diện của một mối quan hệ khi bạn xem xét nó. Tại thời điểm đó, đó là một chuyến đi vòng quanh hiệu suất chậm hơn đầy đủ khôn ngoan.
ttugates

3

Câu hỏi thứ hai của bạn

Có bao nhiêu cột có thể được sử dụng cùng nhau làm khóa chính trong một bảng nhất định?

là triển khai cụ thể: nó được định nghĩa trong DBMS thực tế đang được sử dụng. [1], [2], [3] Bạn phải kiểm tra đặc điểm kỹ thuật của hệ thống cơ sở dữ liệu mà bạn sử dụng. Một số rất chi tiết, một số thì không. Tìm kiếm trên web về những giới hạn như vậy có thể khó khăn vì thuật ngữ khác nhau. Thuật ngữ khóa chính tổng hợp nên là bắt buộc;)

Nếu bạn không thể tìm thấy thông tin rõ ràng, hãy thử tạo một cơ sở dữ liệu thử nghiệm để đảm bảo rằng bạn có thể mong đợi việc xử lý ổn định (và cụ thể) đối với các vi phạm giới hạn (dự kiến). Hãy cẩn thận để có được thông tin chính xác về điều này: đôi khi các giới hạn được tích lũy và bạn sẽ thấy các kết quả khác nhau với các bố cục cơ sở dữ liệu khác nhau.



2

Sử dụng khóa chính trên nhiều bảng sẽ có ích khi bạn đang sử dụng bảng trung gian trong cơ sở dữ liệu quan hệ.

Tôi sẽ sử dụng một cơ sở dữ liệu mà tôi đã từng tạo cho một ví dụ và cụ thể là ba bảng trong bảng đó. Tôi đã tạo cơ sở dữ liệu cho webcomic vài năm trước. Một bảng được gọi là "truyện tranh" —một danh sách tất cả truyện tranh, tiêu đề của chúng, tên tệp hình ảnh, v.v. Khóa chính là "comicnum".

Bảng thứ hai là "các ký tự" - tên của họ và mô tả ngắn gọn. Khóa chính nằm trên "charname".

Vì mỗi truyện tranh — với một số ngoại lệ — có nhiều nhân vật và mỗi nhân vật xuất hiện trong nhiều truyện tranh, nên việc đặt một cột trong "nhân vật" hoặc "truyện tranh" để phản ánh điều đó là không thực tế. Thay vào đó, tôi đặt một bảng thứ ba được gọi là "truyện tranh", và đó là danh sách các nhân vật xuất hiện trong truyện tranh. Vì bảng này về cơ bản kết hợp với hai bảng, nó cần có nhưng hai cột: charname và comicnum, và khóa chính nằm trên cả hai.


1

Chúng tôi tạo các khóa chính tổng hợp để đảm bảo các giá trị cột duy nhất tạo nên một bản ghi duy nhất. Đó là một hạn chế giúp ngăn chặn việc chèn dữ liệu không được trùng lặp.

nghĩa là: Nếu tất cả Id sinh viên và số giấy khai sinh được chỉ định duy nhất cho một người. Sau đó, sẽ là một ý tưởng hay nếu bạn đặt khóa chính cho một người thành một thành phần của id sinh viên và số giấy khai sinh vì nó sẽ ngăn bạn vô tình chèn hai người có id sinh viên khác nhau và cùng một giấy khai sinh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.