Mỗi bảng nên có một khóa chính?


339

Tôi đang tạo một bảng cơ sở dữ liệu và tôi không có khóa chính logic được gán cho nó. Vì vậy, tôi đang suy nghĩ về việc để nó mà không có khóa chính, nhưng tôi cảm thấy có chút tội lỗi về nó. Tôi có nên

Mỗi bảng nên có một khóa chính?


5
Bạn có thể cho biết thêm một số chi tiết về bảng? Câu trả lời có lẽ là "có".
Ryan Bair

7
Có, mỗi và mỗi bảng nên có khóa chính.
Syed Tayyab Ali

Câu trả lời:


312

Câu trả lời ngắn gọn: .

Câu trả lời dài:

  • Bạn cần bàn của bạn để có thể tham gia vào một cái gì đó
  • Nếu bạn muốn bảng của mình được phân cụm, bạn cần một loại khóa chính.
  • Nếu thiết kế bảng của bạn không cần khóa chính, hãy suy nghĩ lại về thiết kế của bạn: rất có thể, bạn đang thiếu một cái gì đó. Tại sao giữ hồ sơ giống hệt nhau?

Trong MySQL, công cụ lưu trữ InnoDB luôn tạo khóa chính nếu bạn không chỉ định rõ ràng, do đó tạo thêm một cột mà bạn không có quyền truy cập.

Lưu ý rằng một khóa chính có thể được tổng hợp.

Nếu bạn có bảng liên kết nhiều-nhiều, bạn tạo khóa chính trên tất cả các trường liên quan đến liên kết. Do đó, bạn đảm bảo rằng bạn không có hai hoặc nhiều bản ghi mô tả một liên kết.

Bên cạnh các vấn đề về tính nhất quán logic, hầu hết các công cụ RDBMS sẽ được hưởng lợi từ việc đưa các trường này vào một chỉ mục duy nhất.

Và vì bất kỳ khóa chính nào liên quan đến việc tạo một chỉ mục duy nhất, bạn nên khai báo nó và nhận được cả tính nhất quán và hiệu suất logic.

Xem bài viết này trong blog của tôi để biết lý do tại sao bạn phải luôn tạo một chỉ mục duy nhất trên dữ liệu duy nhất:

PS Có một số trường hợp rất, rất đặc biệt khi bạn không cần khóa chính.

Chủ yếu là chúng bao gồm các bảng nhật ký không có bất kỳ chỉ mục nào vì lý do hiệu suất.


họ vẫn có một khóa chính, khóa tổng hợp
kristof

2
@annakata: họ nên có khóa chính tổng hợp
Quassnoi

1
"Và vì bất kỳ KHÓA CHÍNH nào liên quan đến việc tạo ra một chỉ mục ĐỘC ĐÁO" là không đúng với Oracle. Người ta có thể sử dụng một chỉ mục không duy nhất để thực thi khóa chính. Trong thực tế, đôi khi YÊU CẦU rằng các ràng buộc PK và duy nhất sử dụng các chỉ mục không duy nhất.
Stephanie Trang

3
Chỉ cần một nhận xét về câu hỏi tu từ "Tại sao giữ hồ sơ giống hệt nhau?". Lưu ý rằng chỉ cần thêm PK sẽ không đảm bảo rằng không có sự trùng lặp. Thông thường PK không hiển thị cho người dùng, do đó điều quan trọng là trong các trường hiển thị, có thể chứa dữ liệu trùng lặp. Tùy thuộc vào thiết kế của bạn, điều này có thể được mong muốn hay không.
Rossco

1
Chìa khóa không có gì để liên kết. Và đối số phân cụm phụ thuộc vào DBMS mà bạn sử dụng và trộn lẫn các cân nhắc logic và vật lý.
Jon Heggland

35

Luôn luôn tốt nhất để có một khóa chính. Bằng cách này, nó đáp ứng dạng bình thường đầu tiên và cho phép bạn tiếp tục theo đường dẫn chuẩn hóa cơ sở dữ liệu .

Như những người khác đã nêu, có một số lý do không có khóa chính, nhưng hầu hết sẽ không bị tổn hại nếu có khóa chính


5
@PaulSuart Dữ liệu không cần phải luôn ở dạng bình thường. Trong thực tế, khi dữ liệu trở nên khổng lồ, nó không nên được giữ ở dạng bình thường nếu không việc truy cập dữ liệu sẽ chậm một cách khủng khiếp đối với các truy vấn khi tham gia bảng, v.v ... Các dạng thông thường là "lý tưởng hóa" và thực tế chỉ có thể khi dữ liệu không được mong đợi tăng lên khổng lồ.
Pacerier

13

Gần như bất cứ khi nào tôi tạo một bảng mà không có khóa chính, nghĩ rằng tôi sẽ không cần một bảng, cuối cùng tôi đã quay lại và thêm một bảng. Bây giờ tôi tạo ngay cả các bảng tham gia của mình với trường nhận dạng được tạo tự động mà tôi sử dụng làm khóa chính.


12
Bảng tham gia LÀ khóa chính - một tổ hợp, bao gồm các PK của cả hai bản ghi được nối. Ví dụ: CREATE TABLE PersonOrder (PersonId int, OrderId int, PRIMARY KEY (PersonId, OrderId)).
Keith Williams

3
Có, nhưng nếu Bảng Liên kết cũng có thuộc tính thứ ba, hãy nói "OrderDate". Bạn có thể thêm nó vào khóa tổng hợp không? IMHO không - bởi vì nó có thể giảm hơn nữa và không phục vụ đặc tính không thể giảm mà một khóa chính nên có.
stevek

13

Ngoại trừ một vài trường hợp rất hiếm (có thể là bảng quan hệ nhiều-nhiều hoặc bảng bạn tạm thời sử dụng để tải số lượng lớn dữ liệu), tôi sẽ nói với câu:

Nếu nó không có khóa chính, thì đó không phải là bảng!

Marc


9
Nói đúng ra câu đó là sai. Các bảng có thể là "Xem bảng" được tạo bởi Ngôn ngữ truy vấn của bạn. Một RDBMS bao gồm các quan hệ không phải là bảng. Câu đó sẽ nói: "Nếu nó không có khóa chính, thì đó không phải là quan hệ!".
stevek

Hoặc có lẽ, "nếu không có khóa ứng cử viên thì đó không phải là bảng quan hệ". Nhưng hãy xem những trường hợp rất hiếm khi có một bảng không thể hiện mối quan hệ.
Walter Mitty

Tại sao một bảng nhiều-nhiều có một khóa chính? Bạn có thể tạo một khóa chính riêng biệt và sau đó tạo một chỉ mục duy nhất cho việc thay thế các khóa ngoại. Tôi nghĩ sẽ tốt hơn nếu có một khóa chính trên mỗi bàn. Ngay cả trên bảng tải số lượng lớn, bạn có thể muốn xác định riêng một khóa chính không bao gồm dữ liệu được nhập vì nó có thể giúp bạn xác định các bản ghi trùng lặp trong quy trình ETL. Dường như với tôi rằng mỗi bảng vẫn phải có một khóa chính, ngay cả khi nó là một bộ lưu trữ nhiều hơn một chút. Một bảng được tạo bởi một khung nhìn là một tập hợp con của một bảng chứ không phải chính bảng đó.
John Ernest

1
Trong bảng nhiều mối quan hệ, bạn có thể tạo khóa chính tổng hợp bao gồm cả id cho các mối quan hệ.
Jaap

8

Bạn có bao giờ cần phải tham gia bảng này đến các bảng khác? Bạn có cần một cách để xác định duy nhất một hồ sơ? Nếu câu trả lời là có, bạn cần một khóa chính. Giả sử dữ liệu của bạn giống như bảng khách hàng có tên của những người là khách hàng. Có thể không có khóa tự nhiên vì bạn cần địa chỉ, email, số điện thoại, v.v. để xác định xem Sally Smith này có khác với Sally Smith không và bạn sẽ lưu trữ thông tin đó trong các bảng có liên quan vì người đó có thể có điện thoại, phụ kiện , email, v.v ... Giả sử Sally Smith kết hôn với John Jones và trở thành Sally Jones. Nếu bạn không có bảng onthe khóa nhân tạo, khi bạn cập nhật tên, bạn chỉ cần đổi 7 Sally Smith thành Sally Jones mặc dù chỉ một trong số họ kết hôn và đổi tên.

Bạn nói rằng bạn không có khóa tự nhiên, do đó bạn không có bất kỳ kết hợp trường nào để tạo sự độc đáo, điều này làm cho khóa nhân tạo trở nên quan trọng.

Tôi đã tìm thấy bất cứ khi nào tôi không có khóa tự nhiên, khóa nhân tạo là điều bắt buộc tuyệt đối để duy trì tính toàn vẹn dữ liệu. Nếu bạn có khóa tự nhiên, bạn có thể sử dụng khóa đó làm trường khóa thay thế. Nhưng cá nhân trừ khi khóa tự nhiên là một trường, tôi vẫn thích khóa nhân tạo và chỉ mục duy nhất trên khóa tự nhiên. Bạn sẽ hối tiếc về sau nếu bạn không đặt nó vào.


7

Chỉ cần thêm nó, bạn sẽ xin lỗi sau này khi bạn không (chọn, xóa. Liên kết, v.v.)


6

Đó là một thực hành tốt để có PK trên mỗi bàn, nhưng đó không phải là PHẢI. Rất có thể bạn sẽ cần một chỉ mục duy nhất và / hoặc một chỉ mục được nhóm (có PK hay không) tùy thuộc vào nhu cầu của bạn.

Kiểm tra các phần Khóa chính và Chỉ mục được nhóm trên Sách trực tuyến (đối với SQL Server)

"Các ràng buộc PRIMARY KEY xác định cột hoặc tập hợp các cột có các giá trị xác định duy nhất một hàng trong bảng. Không có hai hàng trong bảng có thể có cùng giá trị khóa chính. Bạn không thể nhập NULL cho bất kỳ cột nào trong khóa chính. khuyên bạn nên sử dụng một cột số nguyên nhỏ làm khóa chính. Mỗi bảng nên có một khóa chính. Một cột hoặc tổ hợp các cột đủ điều kiện làm giá trị khóa chính được gọi là khóa ứng viên. "

Nhưng sau đó cũng kiểm tra điều này: http://www.aisintl.com/case/primary_and_forign_key.html



4
Trang đó khá là ngu ngốc. Đầu tiên, một khóa chính là cần thiết cho lý do hiệu suất. Bằng cách đọc trang của anh ấy tôi biết rằng việc thêm ID vào bảng sách là vô ích vì văn bản của sách là duy nhất; rõ ràng, anh chàng không bao giờ làm việc với cơ sở dữ liệu. Nhưng anh ta cũng có vấn đề trong việc hiểu những gì anh ta chỉ trích. Trang viết rằng 1) giá trị PK tham chiếu một hàng 2) bạn có thể nối 2 bảng bằng bất kỳ tập hợp cột nào. Không có mâu thuẫn. Thật đáng kinh ngạc khi một tác giả bài báo học thuật không hiểu rất cơ bản của lý thuyết quan hệ.
Federico Razzoli

1
"Đầu tiên, một khóa chính là cần thiết cho lý do hiệu suất" điều này không chính xác, PK không ảnh hưởng trực tiếp đến hiệu suất. Không có PK có thể dẫn đến nhiều vấn đề (xác định một hàng, tham gia, v.v.) nhưng hiệu suất không phải là một trong số đó. Khi bạn tạo PK trên bảng, máy chủ SQL sẽ tạo một chỉ mục cụm duy nhất, chỉ mục đó ảnh hưởng đến hiệu suất chứ không phải chính PK. Như một ví dụ thực tế, bảng của tôi có một chỉ mục được nhóm trên cột ngày và PK trên trường GUID, vì các hàng của tôi phải được sắp xếp theo thứ tự vật lý qua cột ngày trong bảng vì tất cả các truy vấn đều có phạm vi ngày (trong trường hợp của tôi).
endo64

Chỉ mục được nhóm đó là một hương vị của khóa chính, được tạo bởi SQL Server và một số DBMS khác. Bạn có chắc chắn rằng đó là một ý tưởng tốt để sử dụng nó? Ví dụ, trong MySQL, nó không vì một số lý do không có giấy tờ.
Federico Razzoli

1
Hãy nhớ rằng GUID không phải là loại tối ưu cho PK, trong InnoDB. Tất cả các chỉ mục đều chứa tham chiếu đến PK vì vậy, PK càng lớn, càng lớn sẽ là tất cả các chỉ mục khác.
Federico Razzoli

6

Không đồng ý với câu trả lời được đề xuất. Câu trả lời ngắn gọn là: KHÔNG .

Mục đích của khóa chính là xác định duy nhất một hàng trên bảng để tạo mối quan hệ với một bảng khác. Theo truyền thống, một giá trị số nguyên tăng tự động được sử dụng cho mục đích này, nhưng có các biến thể cho điều này.

Tuy nhiên, có một số trường hợp, ví dụ ghi dữ liệu chuỗi thời gian, trong đó sự tồn tại của khóa như vậy đơn giản là không cần thiết và chỉ chiếm bộ nhớ. Làm cho một hàng độc đáo chỉ đơn giản là ... không bắt buộc!

Một ví dụ nhỏ: Bảng A: LogData

Columns:  DateAndTime, UserId, AttribA, AttribB, AttribC etc...

Không cần khóa chính.

Bảng B: Người dùng

Columns: Id, FirstName, LastName etc. 

Khóa chính (Id) cần thiết để được sử dụng làm "khóa ngoại" cho bảng LogData.


3

Tôi biết rằng để sử dụng một số tính năng nhất định của Gridview trong .NET, bạn cần một khóa chính để Gridview biết được hàng nào cần cập nhật / xóa. Thực hành chung nên có một cụm khóa chính hoặc cụm khóa chính. Cá nhân tôi thích cái trước.


3

Để làm cho nó bằng chứng trong tương lai bạn thực sự nên. Nếu bạn muốn sao chép nó, bạn sẽ cần một cái. Nếu bạn muốn tham gia nó vào một bảng khác, cuộc sống của bạn (và của những kẻ ngốc đáng thương phải duy trì nó trong năm tới) sẽ dễ dàng hơn rất nhiều.


Tôi không tin rằng điều đó là cần thiết, nhưng "hãy làm điều đó bởi vì nếu không thì ai đó sẽ phải giải quyết hậu quả sau này" là đủ để khiến tôi thất bại trong việc thực hiện nó. Tôi luôn có thể thả cột sau nếu có vẻ đáng để thử thu nhỏ nó xuống ...
ArtOfWarfare

2

Tôi luôn có một khóa chính, ngay cả khi ban đầu tôi chưa có mục đích nào cho nó. Đã có một vài lần cuối cùng tôi cần một PK trong một bảng không có và nó luôn gặp nhiều rắc rối hơn khi đặt nó sau này. Tôi nghĩ rằng có nhiều mặt trái để luôn luôn bao gồm một.


2

Tôi đang trong vai trò duy trì ứng dụng được tạo bởi nhóm phát triển ra nước ngoài. Bây giờ tôi có tất cả các loại vấn đề trong ứng dụng vì lược đồ cơ sở dữ liệu ban đầu không chứa các KHÓA CHÍNH trên một số bảng. Vì vậy, xin vui lòng không để người khác đau khổ vì thiết kế kém của bạn. Luôn luôn là ý tưởng tốt để có các khóa chính trên bàn.


1

Tóm lại, không. Tuy nhiên, bạn cần lưu ý rằng các hoạt động CRUD truy cập của khách hàng nhất định cần có nó. Để chứng minh trong tương lai, tôi có xu hướng luôn sử dụng các khóa chính.


1

Nếu bạn đang sử dụng Hibernate thì không thể tạo Thực thể mà không có khóa chính. Vấn đề này có thể tạo ra sự cố nếu bạn đang làm việc với cơ sở dữ liệu hiện có được tạo bằng các tập lệnh sql / ddl đơn giản và không có khóa chính nào được thêm vào

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.