2009-05-06 12 views
16

Tôi có nên luôn có khóa chính trong các bảng cơ sở dữ liệu của mình không?Nếu bảng cơ sở dữ liệu luôn có khóa chính không?

Chúng ta hãy gắn thẻ SO. Bạn có thể thấy thẻ trong bất kỳ sửa đổi nào, có khả năng là trong bảng tag_rev có số postID và số sửa đổi. Tôi có cần một PK cho điều đó không?

Cũng vì nó nằm trong bảng rev và hiện không sử dụng thẻ nên là một blob tagID thay vì nhiều mục của nhiều cặp post_id tagid?

+16

Tôi hy vọng bạn nhận thấy câu cuối cùng của bạn đã bị coi là không thể hiểu được bởi nhiều người. – kch

+0

Có thể trùng lặp [Mỗi bảng và mỗi bảng có khóa chính không?] (Https://stackoverflow.com/questions/840162/should-each-and-every-table-have-a-primary-key) –

Trả lời

9

Bạn nên cố gắng để có một khóa chính trong bất kỳ bảng không tầm thường nơi bạn đang có khả năng muốn truy cập (hoặc cập nhật hoặc xóa) các hồ sơ cá nhân của khóa đó. Các khóa chính có thể bao gồm nhiều cột và chính thức nói, sẽ là siêu khóa có sẵn ngắn nhất; có nghĩa là, các nhóm cột có sẵn ngắn nhất, cùng nhau, xác định duy nhất bất kỳ hàng nào.

Tôi không biết lược đồ cơ sở dữ liệu Stack Overflow trông như thế nào (và từ một số điều tôi đã đọc trên blog của Jeff, tôi không muốn), nhưng trong trường hợp bạn mô tả, nó hoàn toàn có thể có một khóa chính trên số nhận dạng bài đăng, số sửa đổi và giá trị thẻ; chắc chắn, đó sẽ là siêu phím ngắn nhất (và duy nhất) có sẵn.

Đối với điểm thứ hai của bạn, có thể hợp lý để tranh luận về giá trị tổng hợp trong bảng lưu trữ, nó đi ngược lại nguyên tắc mỗi giao điểm hàng/cột trong bảng phải chứa một giá trị duy nhất. Mặc dù nó có thể đơn giản hóa việc phát triển, không có lý do gì bạn không thể giữ một bảng bình thường với siêu dữ liệu đã được phiên bản, thậm chí cho một thứ gì đó tầm thường như các thẻ.

10

A bảng phải có khóa chính để bạn có thể xác định mỗi hàng duy nhất với nó.

Về mặt kỹ thuật, bạn có thể có bảng không có khóa chính, nhưng bạn sẽ phá vỡ các quy tắc thiết kế cơ sở dữ liệu tốt.

+0

Trong một ứng dụng kế thừa tôi duy trì có một vài bảng chỉ có một hàng, theo thiết kế. Và một số bảng sẽ không có nhiều hơn mười hàng hoặc nhiều hơn (tra cứu loại này hay loại khác). Có hoàn toàn không có ý nghĩa của việc có một khóa chính trong tình huống như vậy. Ít nhất theo ý kiến ​​của tôi, anyway. – Cyberherbalist

+2

@Cyberherbalist: Ngay cả trong trường hợp đó, nếu bạn đang sử dụng bảng đó theo lập trình, bạn có thể cần một cách để xác định từng hàng riêng biệt. Cũng lưu ý rằng có một khóa chính không có nghĩa là có * * khóa * khóa chính * riêng *. Bạn có thể có kết hợp các cột làm khóa chính. BTW, nó hoàn toàn hợp lệ để bỏ qua các mẫu và quy tắc khi bạn nghĩ rằng chúng không có ý nghĩa trong tình huống cụ thể của bạn nhưng đối với phần lớn các trường hợp, không có khóa chính gây tổn hại. –

+0

Chính xác. Tôi nghĩ WTF khi tôi đọc cuốn sách "Cơ sở dữ liệu" của trường Trung học (Anh), cho MS Access. Trích dẫn - "Nếu Access yêu cầu bạn xác định khóa chính, hãy nhấp vào Không." –

4

Xem câu hỏi liên quan này về việc có cần số số nguyên khóa chính hay không. Một trong những câu trả lời sử dụng được gắn thẻ như một ví dụ:

Are there any good reasons to have a database table without an integer primary key

Để thảo luận hơn về gắn thẻ và chìa khóa, xem câu hỏi này:

Id for tags in tag systems

+0

Tuy nhiên, đây không phải là câu hỏi. @acidzombie không hỏi về PK không phải số nguyên, nhưng trường hợp chung có hay không có khóa chính của bất kỳ loại nào (tức là chuỗi). – Cyberherbalist

+0

Cảm ơn, tôi đã chỉnh sửa để làm rõ các câu hỏi liên quan như thế nào. –

-1

Cơ sở dữ liệu không có chìa khóa, mỗi gia nhập, nhưng các bảng cấu thành của chúng có thể. Tôi giả sử bạn có nghĩa là, nhưng chỉ trong trường hợp ...

Dù sao, các bảng có số lượng lớn hàng phải hoàn toàn có khóa chính; các bảng chỉ có một vài hàng không cần chúng, nhất thiết, mặc dù chúng không bị tổn thương. Nó phụ thuộc vào cách sử dụng và kích thước của bảng. Purists sẽ đặt các khóa chính trong mỗi bảng. Điều này không sai; và không bỏ qua PK trong các bảng nhỏ.

Đã chỉnh sửa để thêm liên kết tới bài viết blog của tôi về câu hỏi này, trong đó tôi thảo luận một trường hợp trong đó nhân viên quản trị cơ sở dữ liệu không xem xét cần thiết bao gồm khóa chính trong bảng cụ thể. Tôi nghĩ điều này minh họa quan điểm của tôi một cách đầy đủ.

Cyberherbalist's Blog Post on Primary Keys

+0

Một bảng hàng đơn không cần khóa chính, bất kỳ điều gì khác cần phải có một bảng được xác định để tránh trùng lặp. – jmoreno

+1

Có, nói chung, nhưng quy tắc kinh doanh xác định liệu các bản sao có được phép hay không - không thể tưởng tượng rằng các mục nhập trùng lặp trong một bảng có thể không chỉ được phép, mà được mong đợi. Nó phụ thuộc vào những gì đang được lưu trữ, và những gì sử dụng được làm bằng nó. BTW cảm ơn cho hit đại diện - câu trả lời này không thực sự mâu thuẫn với câu trả lời được chấp nhận. Chủ nghĩa chuyên chế của bạn được ghi nhận. – Cyberherbalist

+0

Nếu bạn đang lưu trữ các bản sao chính xác, bạn đang lưu trữ sai. Đối với các đại diện hit, loại bỏ slam ở những người nghĩ rằng mỗi bảng nên có một PK, và tôi sẽ loại bỏ nó. – jmoreno

0

Nếu không có PK, bạn sẽ cập nhật hoặc xóa một hàng như thế nào? Nó sẽ là không thể! Thành thật mà nói tôi đã sử dụng một vài lần bảng mà không cần PK, ví dụ để lưu trữ các bản ghi hoạt động, nhưng ngay cả trong trường hợp này nó được khuyến khích để có một vì các dấu thời gian không thể đủ chi tiết. Bảng tạm thời là một ví dụ khác. Nhưng theo lý thuyết quan hệ thì PK là bắt buộc.

+1

Không thể? Nah. Hàng trong một bảng nhỏ có thể được xác định duy nhất mà không có PK.Nếu nó là một bảng tra cứu nhỏ (nơi tôi thấy sử dụng nhiều nhất các bảng PK-ít hơn), luôn có một giá trị có thể là khóa, nhưng ở bất kỳ tỷ lệ nào cũng là một cách để xác định duy nhất hàng ngay cả khi không có PK (hoặc bạn có thể chỉnh sửa hàng bằng cách mở bảng bằng SSMS). Nhưng nó có vẻ là hiệu quả hơn để sử dụng một khóa primay và một lệnh Sql. – Cyberherbalist

+0

@Lluis, bạn sử dụng DELETE ... LIMIT 1 hoặc UPDATE ... LIMIT 1. @Cyberherbalist, các hàng không thể luôn được xác định duy nhất vì không có gì ngăn tất cả các giá trị cột giống nhau, nhưng bạn có thể giới hạn số bị ảnh hưởng bởi một truy vấn. – Draemon

0

bạn nên có chìa khóa và mối quan hệ. Giúp đỡ rất nhiều. tuy nhiên nếu ứng dụng của bạn đủ tốt để xử lý các mối quan hệ thì bạn có thể bỏ qua các phím (mặc dù tôi khuyên bạn nên có các khóa này)

0

Vì tôi sử dụng Subsonic, tôi luôn tạo khóa chính cho tất cả các bảng của mình. Nhiều thư viện trừu tượng DB yêu cầu một khóa chính để làm việc.

Lưu ý: điều đó không trả lời được câu "Lý thuyết thống nhất Grand" của câu hỏi của bạn, nhưng tôi chỉ nói rằng trong thực tế, đôi khi bạn PHẢI tạo một khóa chính cho mỗi bảng.

1

Tôi tin chắc rằng mọi bảng nên có cách xác định duy nhất một bản ghi. Đối với 99% các bảng, đây là khóa chính. Đối với phần còn lại bạn có thể lấy đi với một chỉ số duy nhất (tôi đang suy nghĩ một cột tra cứu loại bảng ở đây). Bất cứ lúc nào tôi phải làm việc với một cái bàn mà không có cách nào để xác định duy nhất hồ sơ, đã có rắc rối.

Tôi cũng tin rằng nếu bạn đang sử dụng khóa thay thế làm PK của mình, bạn nên, có thể có một chỉ mục riêng biệt trên bất kỳ kết hợp nào của trường tạo nên khóa tự nhiên. Tôi nhận ra có quá nhiều lần khi bạn không có một chìa khóa tự nhiên thực sự (tên không phải là duy nhất hoặc những gì làm cho một cái gì đó độc đáo có thể được lan truyền trên một số bảng chachild), nhưng nếu bạn có một, xin vui lòng hãy chắc chắn rằng nó có chỉ mục duy nhất hoặc được tạo dưới dạng PK.

4

Tôi có xu hướng đồng ý rằng hầu hết các bảng phải có khóa chính. Tôi chỉ có thể nghĩ đến hai lần mà nó không có ý nghĩa để làm điều đó.

  1. Nếu bạn có bảng liên quan đến các khóa với các khóa khác. Ví dụ: để liên kết user_id với answer_id, bảng đó sẽ không cần khóa chính.
  2. Bảng ghi nhật ký, chỉ có mục đích thực sự là tạo đường mòn kiểm tra.

Về cơ bản, nếu bạn đang viết một bảng có thể cần được tham chiếu trong mối quan hệ khóa ngoại thì khóa chính là quan trọng, và nếu bạn không tích cực thì sẽ không PK. :)

+1

Ở điểm 1, bạn nên có khóa chính kết hợp (user_id, answer_id). Ở điểm 2, tôi sẽ mong đợi một cột dấu thời gian, nhưng nếu có thể có hai hàng giống hệt nhau (dấu thời gian giống nhau và thông điệp), tôi chắc chắn muốn biết rằng có điều gì đó đã xảy ra hai lần và có thể xử lý riêng các sự kiện đó. "13: 15 thấu chi gấp đôi" là rất khác với "533-13: thấu chi gấp đôi gấp đôi, 534-13: thấu chi gấp đôi 15" chẳng hạn. – Draemon

+1

@Draemon - Nếu bạn có hai cột trong một bảng, có một khóa tổng hợp là quá mức cần thiết, IMO, vì bạn thực sự không nhận được bất kỳ lợi ích nào. Nếu bạn có thể có hai sự kiện xảy ra cùng một lúc thì bạn có vấn đề lớn hơn, nếu bạn không mong đợi hai bản cập nhật cùng một lúc trên cùng một bản ghi. –

0

Nếu đó là bảng tham gia thì tôi sẽ không nói rằng bạn cần khóa chính. Giả sử, ví dụ, bạn có các bảng PERSONS, SICKPEOPLE và ILLNESSES. Bảng ILLNESSES có những thứ như cảm cúm, lạnh, vv, mỗi cái có một khóa chính. NGƯỜI có những thứ thông thường về con người, mỗi người cũng có một khóa chính. Bảng SICKPEOPLE chỉ có những người trong đó bị bệnh và có hai cột, PERSONID và ILLNESSID, các khóa ngoại trở lại các bảng tương ứng của chúng và không có khóa chính. Bảng PERSONS và ILLNESSES chứa các thực thể và thực thể nhận các khóa chính. Các mục trong bảng SICKPEOPLE không phải là thực thể và không nhận được khóa chính.

+0

Tôi có thể đặt một khóa chính (hoặc ít nhất một chỉ mục duy nhất) trên bảng SICKPEOPLE (bao gồm cả hai cột) để đảm bảo rằng bạn không vô tình chèn cùng một hàng hai lần. –

+0

Điểm tốt. Như bạn nói, bạn có thể tránh được vấn đề chèn trùng lặp bằng cách thêm một ràng buộc hoặc chỉ mục duy nhất trên sự kết hợp của PERSONID và ILLNESSID trong bảng SICKPEOPLE. Tại momen, tôi có khuynh hướng không ủng hộ việc thêm các khóa chính vào các bảng như thế này bởi vì nó giúp làm rõ rằng nó không phải là một thực thể. – lumpynose

3

Từ MySQL 5,5 Reference Manual phần 13.1.17:

Nếu bạn không có một PRIMARY KEY và một ứng dụng yêu cầu các PRIMARY KEY trong bảng của bạn, MySQL trả về chỉ số UNIQUE đầu tiên mà không có cột NULL như KEY CHÍNH.

Vì vậy, về mặt kỹ thuật, câu trả lời là không. Tuy nhiên, như những người khác đã nêu, trong hầu hết các trường hợp, nó khá hữu ích.

+0

Những gì không ai đề cập đến là một khóa chính có thể là nhiều cột mà là những gì tôi làm bây giờ –

+1

Rob đã đề cập đến nó. Có lẽ bạn nên đánh dấu [câu trả lời của mình] (http://stackoverflow.com/a/831884/2430274) như được chấp nhận? – emisilva

+0

Hey anh ấy đã làm ... có lẽ tôi muốn đợi cho đến khi tôi thử nó và quên chấp nhận nó. Dưới đây là một upvote –