2008-09-02 14 views
14

tôi có các bảng sau trong cơ sở dữ liệu của tôi rằng có một nhiều-nhiều mối quan hệ, được thể hiện bằng một bảng kết nối đó có các phím nước ngoài vào khóa chính của mỗi bảng chính:Một hoặc hai khóa chính trong bảng nhiều người?

  • Widget: WidgetID (PK), Tiêu đề, Giá
  • User: UserID (PK), FirstName, LastName

Giả sử rằng mỗi sự kết hợp với người sử dụng widget là duy nhất. Tôi có thể thấy hai tùy chọn cho cách cấu trúc bảng kết nối định nghĩa mối quan hệ dữ liệu:

  1. UserWidgets1: UserWidgetID (PK), WidgetID (FK), UserID (FK)
  2. UserWidgets2: WidgetID (PK, FK), UserID (PK, FK)

Tùy chọn 1 có một cột duy nhất cho Khóa chính. Tuy nhiên, điều này có vẻ không cần thiết vì dữ liệu duy nhất được lưu trữ trong bảng là mối quan hệ giữa hai bảng chính và mối quan hệ này có thể tạo thành một khóa duy nhất. Do đó, dẫn đến tùy chọn 2, có khóa chính hai cột, nhưng mất mã định danh duy nhất một cột mà tùy chọn 1 có. Tôi cũng có thể tùy ý thêm chỉ mục duy nhất gồm hai cột (WidgetID, UserID) vào bảng đầu tiên.

Có sự khác biệt thực sự nào giữa hai lý do hiệu suất, hoặc bất kỳ lý do nào để thích cách tiếp cận này hơn cách khác để cấu trúc bảng nhiều người dùng đến nhiều người dùng không?

+0

Các chỉ mục bạn cần được quyết định bởi các yêu cầu truy vấn của bạn, không phải là thiết kế lược đồ của bạn. – dkretz

Trả lời

24

Bạn chỉ có một khóa chính trong cả hai trường hợp. Cái thứ hai được gọi là khóa ghép. Không có lý do chính đáng để giới thiệu một cột mới. Trong thực tế, bạn sẽ phải giữ một chỉ mục duy nhất trên tất cả các khóa ứng cử viên. Việc thêm một cột mới sẽ không mua gì ngoài chi phí bảo trì.

Go với tùy chọn 2.

+0

Khóa chính có thể được biên dịch - các điều khoản không độc quyền. – paulmurray

+2

@paulmurray: Tôi tin câu trả lời ở trên cho biết rằng bạn có khóa chính trong cả hai trường hợp, bao gồm cả trường hợp bạn có khóa ghép. Bạn có gì để thêm vào đó không? – Apocalisp

0

Vì mỗi kết hợp Người dùng-Widget là duy nhất, bạn nên thể hiện điều đó trong bảng của mình bằng cách kết hợp độc đáo. Nói cách khác, đi với tùy chọn 2. Nếu không, bạn có thể có hai mục nhập với cùng một tiện ích và ID người dùng nhưng ID tiện ích người dùng khác nhau.

0

Các userwidgetid trong bảng đầu tiên là không cần thiết, vì như bạn nói sự độc đáo đến từ sự kết hợp của widgetid và userid.

Tôi sẽ sử dụng bảng thứ hai, giữ các khóa foriegn và thêm một chỉ mục duy nhất trên widgetid và userid.

Vì vậy:

 
userwidgets(widgetid(fk), userid(fk), 
      unique_index(widgetid, userid) 
) 

Có một số lợi preformance trong không có khóa chính phụ, như cơ sở dữ liệu sẽ không cần phải tính toán các chỉ số cho chìa khóa. Trong mô hình trên mặc dù chỉ số này (thông qua unique_index) vẫn được tính toán, nhưng tôi tin rằng điều này dễ hiểu hơn.

2

Lợi ích của khóa chính trong trường hợp này là gì? Xem xét tùy chọn không có khóa chính: UserWidgets3: WidgetID (FK), UserID (FK)

Nếu bạn muốn duy nhất thì sử dụng khóa hợp chất (UserWidgets2) hoặc ràng buộc duy nhất.

Lợi thế hiệu suất thông thường của việc có khóa chính là bạn thường truy vấn bảng bằng khóa chính, nhanh chóng. Trong trường hợp của nhiều bảng nhiều bạn thường không truy vấn bằng khóa chính để không có lợi ích hiệu suất. Các bảng nhiều người được truy vấn bằng khóa ngoài của họ, vì vậy bạn nên xem xét thêm các chỉ mục trên WidgetID và UserID.

2

Tùy chọn 2 là câu trả lời đúng, trừ khi bạn có lý do thực sự tốt để thêm khóa số thay thế (bạn đã thực hiện trong tùy chọn 1).

Cột khóa số thay thế không phải là 'khóa chính'. Các khóa chính về mặt kỹ thuật là một trong những sự kết hợp của các cột xác định duy nhất một bản ghi trong một bảng.

Bất kỳ ai xây dựng cơ sở dữ liệu cũng nên đọc bài viết này http://it.toolbox.com/blogs/database-soup/primary-keyvil-part-i-7327 bởi Josh Berkus để hiểu sự khác biệt giữa các cột khóa số và khóa chính thay thế.

Theo kinh nghiệm của tôi, lý do thực sự duy nhất để thêm khóa số thay thế vào bảng là khóa chính của bạn là khóa phức hợp và cần được sử dụng làm tham chiếu khóa ngoài trong bảng khác. Chỉ khi đó bạn nên nghĩ thêm cột bổ sung vào bảng. Bất cứ khi nào tôi nhìn thấy một cấu trúc cơ sở dữ liệu mà mỗi bảng có một cột 'id' thì cơ hội được thiết kế bởi một người không đánh giá cao mô hình quan hệ và nó sẽ luôn hiển thị một hoặc nhiều vấn đề được xác định trong Josh bài báo.

3

Tôi đồng ý với các câu trả lời trước nhưng tôi có một nhận xét để thêm. Nếu bạn muốn thêm thông tin khác vào mối quan hệ và cho phép nhiều mối quan hệ giữa hai thực thể giống nhau, bạn cần tùy chọn một.

Ví dụ: nếu bạn muốn theo dõi tất cả các lần người dùng 1 đã sử dụng tiện ích 664 trong bảng userwidget thì userid và widgetid không còn độc đáo nữa.

5

Cá nhân, tôi sẽ đã là tổng hợp/thay thế cột quan trọng trong nhiều-nhiều bảng vì những lý do sau đây:

  • Nếu bạn đã sử dụng các phím tổng hợp số trong bảng thực thể của bạn sau đó có tương tự trên các bảng quan hệ duy trì tính thống nhất trong thiết kế và quy ước đặt tên. Có thể là trường hợp trong tương lai chính bản thân bảng nhiều bản trở thành thực thể cha mẹ cho một thực thể cấp dưới cần một tham chiếu duy nhất cho một hàng riêng lẻ.
  • Nó không thực sự sẽ sử dụng nhiều không gian đĩa bổ sung.

Khoá tổng hợp không phải là khóa thay thế cho khóa tự nhiên/hợp chất cũng không trở thành PRIMARY KEY cho bảng đó chỉ vì đó là cột đầu tiên trong bảng, vì vậy tôi đồng ý một phần với bài viết của Josh Berkus. Tuy nhiên, tôi không đồng ý rằng các khóa tự nhiên luôn là ứng cử viên tốt cho PRIMARY KEY's và chắc chắn không nên được sử dụng nếu chúng được sử dụng như khóa ngoài trong các bảng khác.

+0

Tôi nhận thấy điều này đã được trả lời một thời gian dài trước đây, nhưng liệu khóa hợp chất vẫn là một tham chiếu duy nhất cho một hàng riêng lẻ cho một bảng cha (điểm 2 của bạn)? – crush

+1

@crush - vâng, nó sẽ là duy nhất, nhưng để tạo ra một ràng buộc trên một khóa hợp chất là fugly/không nhất quán trên các nền tảng. Tôi thích rõ ràng và nhất quán hơn. Mỗi bảng có một cột nhận dạng. – Guy

5

Tùy chọn 2 sử dụng khóa tổng hợp đơn giản, tùy chọn 1 sử dụng surrogate key. Tùy chọn 2 được ưa thích trong hầu hết các kịch bản và gần với mô hình lreational ở chỗ nó là một khóa ứng cử viên tốt.

Có những tình huống mà bạn có thể muốn sử dụng một chìa khóa thay thế (Option 1)

  1. Bạn không phải là chìa khóa hợp chất là chìa khóa ứng cử viên tốt theo thời gian. Đặc biệt với dữ liệu thời gian (dữ liệu thay đổi theo thời gian). Điều gì xảy ra nếu bạn muốn thêm một hàng khác vào bảng UserWidget với cùng một UserId và WidgetId? Hãy suy nghĩ về việc làm (EmployeeId, EmployeeId) - nó sẽ hoạt động trong hầu hết các trường hợp ngoại trừ nếu ai đó quay trở lại làm việc cho cùng một nhà tuyển dụng sau này
  2. Nếu bạn đang tạo thông điệp/giao dịch kinh doanh hoặc điều gì đó tương tự. sử dụng để tích hợp. Sao chép có thể?
  3. Nếu bạn muốn tạo các cơ chế kiểm toán của riêng bạn (hoặc tương tự) và không muốn các khóa quá dài.

Theo nguyên tắc, khi lập mô hình dữ liệu, bạn sẽ thấy rằng hầu hết các thực thể liên kết (nhiều đến nhiều) là kết quả của sự kiện. Người chiếm dụng việc làm, vật phẩm được thêm vào giỏ vv Hầu hết các sự kiện có sự phụ thuộc thời gian vào sự kiện, trong đó ngày hoặc thời gian có liên quan - trong trường hợp đó, chìa khóa thay thế có thể là lựa chọn thay thế tốt nhất.

Vì vậy, hãy chọn tùy chọn 2, nhưng đảm bảo rằng bạn có mô hình hoàn chỉnh.

1

Tôi sẽ sử dụng cả hai.

Nghe tôi ra:

chủ chốt Hợp chất này rõ ràng là tốt đẹp, đúng con đường để đi trong chừng mực phản ánh ý nghĩa của dữ liệu của bạn đi. Không có câu hỏi.

Tuy nhiên: Tôi đã gặp phải tất cả các loại sự cố khiến hoạt động ngủ đông đúng cách trừ khi bạn sử dụng một khóa chính được tạo duy nhất - một khóa thay thế.

Vì vậy, tôi sẽ sử dụng dữ liệu lôgic và vật lý mô hình. Một hợp lý có khóa hợp chất. Mô hình vật lý - thực hiện mô hình logic - có khóa thay thế và khóa ngoài.