2010-04-19 38 views
19

Tại sao từ chối các phím tổng hợp có lợi cho tất cả các bảng sử dụng một khóa chính có tên là id? Nguyên nhân nói chung là tất cả ORM đều tuân theo điều này.Tại sao một khóa chính lại tốt hơn khóa tổng hợp?

EDIT

Tôi chỉ mới bắt đầu học Ruby on Rails và trong cuốn sách của sự phát triển nhanh nhẹn bởi thực tế có một dòng: --- Rails thực sự không làm việc quá tốt trừ khi mỗi bảng có một số khóa chính. Đó là ít cầu kỳ về tên của cột. Cùng loại dòng tôi đọc khi tôi đang học Doctrine.

EDIT2 Vui lòng kiểm tra liên kết này. Tôi càng ngày càng bối rối thêm về điều này: --- Composite primary keys versus unique object ID field

Từ liên kết ở trên: -

* khóa chính nên liên tục và vô nghĩa; các khóa không thay thế thường thất bại một hoặc cả hai yêu cầu, cuối cùng là

Nếu khóa không đổi, bạn có thể gặp vấn đề cập nhật trong tương lai nếu khóa không có ý nghĩa, có nhiều khả năng thay đổi, tức là không phải là hằng số; xem ở trên

Lấy một ví dụ đơn giản, phổ biến: một bảng các mục Khoảng không quảng cáo. Nó có thể hấp dẫn để làm cho số mặt hàng (mã số SKU, mã vạch, mã phần, hoặc bất cứ điều gì) khóa chính, nhưng sau đó một năm sau tất cả các số mục thay đổi và bạn còn lại với một bản cập nhật rất lộn xộn toàn bộ vấn đề cơ sở dữ liệu ...

EDIT: có một vấn đề bổ sung thực tế hơn triết học. Trong nhiều trường hợp, bạn sẽ tìm thấy một hàng cụ thể bằng cách nào đó, sau đó cập nhật nó hoặc tìm lại nó (hoặc cả hai). Với các phím tổng hợp, có nhiều dữ liệu hơn để theo dõi và hạn chế hơn trong mệnh đề WHERE để tìm lại hoặc cập nhật (hoặc xóa). Nó cũng có thể là một trong những phân đoạn quan trọng có thể đã thay đổi trong thời gian chờ đợi !. Với một phím thay thế, luôn luôn chỉ có một giá trị duy trì (ID thay thế) và theo định nghĩa, nó không thể thay đổi, mà đơn giản hóa tình hình đáng kể. *

+3

Bạn có thể trích dẫn nguồn của mình không? Tôi sử dụng cả hai: khóa tổng hợp và khóa chính ID dựa trên trình tự. Đôi khi người ta thích hợp hơn người kia. – FrustratedWithFormsDesigner

+0

Bạn đang sử dụng ORM nào mà những người ủng hộ luôn sử dụng các phím đơn giản trên các phím tổng hợp? Tôi đã không bao giờ gặp phải một ORM mà không chơi độc đáo với các phím tổng hợp. Theo hiểu biết của tôi, không có lý do chính đáng để đưa ra ví dụ một bàn giao nhau một chìa khóa thay thế của riêng nó. –

+0

@FrustratedWithFormsDesigner @Iain Galloway Tôi đọc điều này trong khi học Doctrine và bây giờ tôi gặp phải điều tương tự khi học Ruby trên đường ray. Hãy cho tôi biết nếu bạn muốn số trang chính xác của cuốn sách mà dòng này được viết .. Tôi là người mới bắt đầu Vì vậy, tôi yêu cầu cho điều thực sự. Không phải qua questiong hoặc tranh luận về điều này. Có nghĩa là tại sao họ đang sử dụng trường ID này. ?? –

Trả lời

21

Tôi không nghĩ rằng có một tuyên bố chăn rằng bạn chỉ nên sử dụng một khóa chính có tên là id.

Hầu hết mọi người sử dụng khóa chính thay thế làm int tự động, vì nó cách ly khóa chính từ lúc nào cần thay đổi, như thể bạn đặt tên người dùng PK và sau đó họ đổi tên hợp pháp. Bạn sẽ phải cập nhật PK và tất cả các cột FK để phản ánh tên mới. nếu bạn đã sử dụng khóa chính thay thế, bạn chỉ cần cập nhật tên của người dùng ở một vị trí (vì các bảng tham gia vào int không phải là tên).

Kích thước của khóa chính là quan trọng vì PK được sao chép vào mọi chỉ mục bạn xây dựng trên bảng. Nếu PK lớn (giống như một chuỗi) bạn có ít phím trên mỗi trang trong chỉ mục và chỉ mục sẽ mất nhiều bộ nhớ cache hơn để lưu trữ nó. Ints là nhỏ.

Có PK tăng tự động cho chính nó là một chỉ mục được nhóm tốt, vì các hàng được lưu trữ theo thứ tự này và không cần phải quay trở lại và làm cho các hàng bị chèn ra để chèn hàng mới, bạn luôn thêm đến cuối bảng.

+0

Trình tự tuần tự hoạt động thực sự tốt, đặc biệt khi bạn cần hợp nhất các tập dữ liệu từ nhiều cơ sở dữ liệu thành một bảng duy nhất. – Juliet

+0

@Juliet, nhưng chúng lớn và không gian chỉ mục lãng phí. Nếu có thể, tốt nhất là kết hợp ID int tăng tự động với cột khác với xác định cơ sở dữ liệu/công ty/v.v. (như 1 hoặc 2 byte int) trong đó hàng đó đến từ vì nó có thể sử dụng ít không gian hơn guid, nhưng vẫn là duy nhất trên tất cả các cơ sở dữ liệu. –

+4

Tôi không khuyên bạn nên sử dụng guids ngoại trừ các trường hợp cạnh –

1
  1. Đối với một ORM một đơn xác định cột với một tên phù hợp như table_id dễ hơn phím tổng hợp . Nhưng mọi hỗ trợ ORM tốt phím tổng hợp.

  2. PK đơn giản có thể dễ dàng được 'được tự động tăng lên' bởi cơ sở dữ liệu. Điều này không giữ phím tổng hợp .

  3. PK đơn giản cũng dễ sử dụng hơn trong các truy vấn . Khi bạn cần tham gia, bạn chỉ phải sử dụng một cột của cả hai mối quan hệ .

Điều này không có nghĩa là các PK đơn giản tốt hơn các kết hợp tổng hợp.

7

Bạn có thể sử dụng cả hai. Trong một số trường hợp khi tạo liên kết giữa một thực thể, bạn có thể sử dụng cả hai khóa thực thể dưới dạng khóa tổng hợp.

Theo quy tắc chung, tôi sử dụng id được tạo cho các thực thể và khóa tổng hợp cho các mối quan hệ.

+0

Đây là phương pháp tương tự mà tôi sử dụng và nó hoạt động khá tốt. –

0

Đối tượng trong lập trình OO có bản sắc bất kể nội dung của chúng. Hàng (tuples) trong cơ sở dữ liệu quan hệ được xác định bởi nội dung của chúng. Vì vậy, khi thực sự thực hiện ORM, tức là ánh xạ đối tượng từ ngôn ngữ lập trình hướng đối tượng đến cơ sở dữ liệu quan hệ, một ID phụ phải được cung cấp khác biệt với các trường và/hoặc thuộc tính mà đối tượng có trong chương trình - trừ khi một hoặc nhiều bằng cách nào đó được biết để xác định các đối tượng duy nhất.

+0

Bạn chắc chắn yêu cầu * khóa chính * trên bàn của bạn, nhưng không có lý do nào phải là một cột đơn. Các khóa chính hỗn hợp rất phổ biến, đặc biệt là trên các bảng nối. –

+0

Vui lòng đọc lại. Tôi không nói các khóa chính được yêu cầu trong các lược đồ cơ sở dữ liệu quan hệ (chúng không), cũng không phải các khóa tổng hợp không phát sinh trong việc thiết kế các lược đồ cơ sở dữ liệu quan hệ (chúng làm). Tôi chỉ muốn nói rằng nếu mô hình cơ sở dữ liệu quan hệ của bạn bị mù * tạo ra * từ một mô hình lớp OO, tất cả các bảng sẽ cần phải có các ID thay thế làm các khóa chính không tương ứng với bất kỳ thuộc tính nào của các lớp đối tượng. Bảng nối sẽ không được tạo trừ khi bạn xử lý các thuộc tính có giá trị bộ sưu tập theo cách đặc biệt. – reinierpost

+0

Bạn có một cách đặc biệt để biểu diễn một mối quan hệ m: m mà không sử dụng bảng nối? –

4

Vâng, đó là cơ bản về giữ JOIN rất đơn giản - đó là một trong đơn giản để hiểu:

SELECT 
    p.ID, p.Name, p.City, 
    c.ID, c.Country, c.ISOCode 
FROM 
    dbo.Parent p 
INNER JOIN 
    dbo.Child c on c.ParentID = p.ID 

hoặc

SELECT 
    p.ID, p.Name, p.City, 
    c.ID, c.Country, c.ISOCode 
FROM 
    dbo.Parent p 
INNER JOIN 
    dbo.Child c ON c.ParentName = p.Name 
    AND c.ParentCity = p.City 
    AND c.ParentCountry = p.Country 

Nếu bạn có các phím composite tiểu học, bất cứ ai tham gia vào bảng của bạn từ một đứa trẻ bảng phải "kéo dọc" tất cả các cột đó, và tất cả các cột đó cũng sẽ có mặt trong bảng con và các câu lệnh JOIN khá lộn xộn. Tốt hơn hết là nên có một khóa (thậm chí thay thế) duy nhất cho JOIN!

+0

Bạn có khuyên bạn nên sử dụng khóa thay thế (thay vì khóa tổng hợp) làm PK cho bảng giao tiếp đại diện cho mối quan hệ nhiều-nhiều? Nếu vậy, tại sao? –

+0

@Iain Galloway: không nhất thiết - bảng giao tiếp cho nhiều mối quan hệ là một trong những trường hợp đặc biệt mà bạn có thể sử dụng một PK tổng hợp để lợi thế của bạn. Nhưng không có hại (ngoại trừ cột phụ) khi thêm PK thay thế ngay cả trong trường hợp này - nó sẽ cho phép bạn dễ dàng quản lý (ví dụ: xóa) các mục từ bảng giao nhau đó –

12

Giới hạn thực sự duy nhất mà tôi đã chạy vào sử dụng các phím tổng hợp liên quan đến việc sử dụng biểu thức IN với truy vấn phụ. Đây là một vấn đề, bởi vì truy vấn con trong biểu thức IN phải trả về một cột đơn (ít nhất là trong T-SQL).

SELECT 
    emp.Name, 
    emp.UserDomain, 
    emp.UserID 
FROM 
    employee emp 
WHERE 
    ???? IN (SELECT e.UserDomain, e.UserID FROM ... /* some complex 
                 non-correlated subquery 
                 or CTE */ 
      ) 

Luôn luôn có nhiều việc xung quanh, nhưng đôi khi nó có thể gây phiền toái.

Đây không phải là lý do để tránh khóa tổng hợp ở những nơi có ý nghĩa khi sử dụng khóa.

0

Câu hỏi của bạn liên quan chặt chẽ đến giải pháp thay thế surrogate (or artificial) keys vs natural keys. Tôi nghĩ rằng không phải là các phím tổng hợp ít được sử dụng hơn, nhưng các phím tự nhiên (là chúng tổng hợp hoặc đơn giản) ít được ưa chuộng hơn khóa nhân tạo.

Lý thuyết cơ sở dữ liệu quan hệ truyền thống xử lý chủ yếu bằng các khóa "tự nhiên", (những cái có ý nghĩa từ quan điểm tên miền doanh nghiệp) và trong trường hợp đó các phím tổng hợp thường được tìm thấy ... một cách tự nhiên.Tuy nhiên, trong những năm sau, thiết kế cơ sở dữ liệu đã được ưa chuộng (mặc dù không độc quyền) mẫu khóa "nhân tạo", thường là một số tuần tự không có ý nghĩa kinh doanh, chỉ phục vụ để xác định duy nhất bản ghi trong bảng(). và có lẽ là đối tượng ở tầng trên).

+1

Các phím tổng hợp vẫn được tìm thấy "một cách tự nhiên" khi sử dụng khóa thay thế . Surrogate vs Natural key là một cuộc tranh luận hoàn toàn riêng biệt! –

+0

Đọc câu hỏi: "Tại sao việc từ chối các phím tổng hợp có lợi cho tất cả các bảng bằng cách sử dụng một khóa chính có tên là id." 'Một khóa chính có tên là' chính xác là khóa thay thế. – leonbloy

+1

Tôi đọc kỹ câu hỏi. Anh ta không đề cập đến chìa khóa tự nhiên chút nào. Các cuộc tranh luận (tự nhiên so với thay thế và đơn giản so với tổng hợp) là hoàn toàn riêng biệt. Các phím tổng hợp thường xuất hiện khi không có khóa tự nhiên. Để biết ví dụ có liên quan, hãy xem ví dụ: http://megocode3.wordpress.com/2008/01/04/understanding-a-sql-junction-table/ Bạn có thể nghĩ ra một lý do chính đáng để trao cho bảng giao lộ đó một chìa khóa thay thế của riêng nó không? –

2

Tôi đã làm việc trên một ứng dụng có khóa chính 11 cột. Nó luôn luôn là niềm vui tuyệt vời retyping danh sách hơn và hơn và hơn mỗi lần tôi muốn đảm bảo tôi đã được cập nhật một hàng. Đó là một trình điều khiển các lỗi, MS-Access không thể đối phó với hơn 10 cột trong một PK, v.v.

Các phím tổng hợp lớn là các mùi thiết kế có nghĩa là bảng chứa các thực thể không đồng nhất hoặc nhà thiết kế không thực sự chắc chắn những gì nó là duy nhất về mỗi thực thể. (Giống như giả định rằng màu tóc, màu mắt và trọng lượng cơ thể là đủ để nhận dạng duy nhất một nhân viên-- đó không phải là chìa khóa tốt vì bạn cần ngày càng nhiều cột để làm việc và cuối cùng sẽ bao gồm các trường dễ bay hơi và thay đổi rất nhiều, như trọng lượng, hoặc đối với một số người có màu tóc hoặc không có.)

0

Mặc dù tôi đồng ý với hầu hết các lý do được đưa ra bởi những người trả lời khác, lý do chính của tôi là thích một số nguyên một cột chính là nó làm cho việc viết giao diện người dùng trở nên dễ dàng hơn nhiều.

Nếu bạn đang sử dụng một số loại điều khiển danh sách để đại diện cho dữ liệu của bạn (danh sách, danh sách, hộp tổ hợp, v.v.), bạn có thể liên kết duy nhất mỗi mục nhập trở lại biểu diễn cơ sở dữ liệu của nó thông qua một giá trị nguyên duy nhất được lưu trữ với mục. Hầu hết các thành phần được viết sẵn đã cho phép bạn đính kèm một số nguyên cho mỗi mục và cho những mục không có, nó rất dễ dàng để mở rộng thành phần để làm như vậy.

Nếu bạn đang chuyển dữ liệu giữa ứng dụng máy chủ và trang web, việc lưu trữ giá trị nhận dạng duy nhất dễ dàng hơn trong thuộc tính id của tiện ích con biểu thị dữ liệu hơn là phải soạn và phân tích nhiều giá trị id.

Các vấn đề liên quan