Một khóa chính có nên bất biến?


26

Một câu hỏi gần đây về stackoverflow đã gây ra một cuộc thảo luận về tính bất biến của các khóa chính. Tôi đã nghĩ rằng đó là một loại quy tắc mà các khóa chính phải là bất biến. Nếu có khả năng một ngày nào đó khóa chính sẽ được cập nhật, tôi nghĩ bạn nên sử dụng khóa thay thế. Tuy nhiên, nó không có trong tiêu chuẩn SQL và một số tính năng "cập nhật theo tầng" của RDBMS cho phép khóa chính thay đổi.

Vì vậy, câu hỏi của tôi là: nó vẫn là một thực tiễn xấu để có một khóa chính có thể thay đổi? Nhược điểm, nếu có, có khóa chính có thể thay đổi là gì?

Câu trả lời:


25

Bạn chỉ cần khóa chính là bất biến nếu nó được liên kết với khóa ngoại hoặc nếu nó được sử dụng làm định danh bên ngoài cơ sở dữ liệu (ví dụ: trong một URL trỏ đến một trang cho mục đó).

Mặt khác, bạn chỉ cần có một khóa có thể thay đổi nếu nó mang một số thông tin có thể thay đổi. Tôi luôn sử dụng khóa thay thế nếu bản ghi không có mã định danh đơn giản, không thay đổi có thể được sử dụng làm khóa.


7
Tại sao bạn " cần khóa chính là bất biến nếu nó được liên kết với khóa ngoại"? Như OP đã đề cập, hầu hết các RDBMS đều có tính năng cập nhật "xếp tầng".
Thanatos

1
@Thanatos nhất (thực tế là tất cả những gì tôi đã gặp) rdbms sẽ không cho phép các khóa chính có thể thay đổi được nhưng vẫn có các bản cập nhật xếp tầng. Một khóa chính, trong trí tuệ dba thường được chấp nhận, không chứa thông tin, chỉ là một định danh bản ghi duy nhất (vì vậy thậm chí không phải là dấu thời gian, phạm vi bản ghi được hoãn lại từ đó, v.v.).
jwenting

5
@jwenting: Có phải chúng ta đang nói về điều tương tự? "Hầu hết các rdbms sẽ không cho phép các khóa chính có thể thay đổi" bao gồm những gì? Cả MySQL và PostgreSQL đều cho phép các khóa chính có thể thay đổi và tôn trọng các bản cập nhật xếp tầng như tôi nghĩ rằng SQL chuẩn nên nói. Ngoài ra, "nói chung chấp nhận trí tuệ dba"? Tôi đã gặp rất nhiều DBA tranh luận về các khóa thay thế và rất nhiều người tranh luận với các khóa tự nhiên.
Thanatos

2
@Thanatos Các lập luận ủng hộ "tất cả các bảng phải thay thế" thiếu các tài liệu tham khảo thư mục, họ trích dẫn "nói chung chấp nhận trí tuệ dba" nhưng họ không bao giờ trích dẫn một cuốn sách. Sách Canonical nói rằng bạn nên sử dụng thay thế nếu: A. không tồn tại khóa tự nhiên, khóa B. nhiều màu được đưa ra 3 cột hoặc C. Bạn sẽ luôn thay đổi khóa. Vì vậy: tự nhiên khi chúng phù hợp, thay thế khi Naturals không phù hợp.
Tulains Córdova

4
@ user61852: Cái gì?
Guffa

15

Một khóa chính phải bao gồm bất kỳ bộ dữ liệu nào là cần thiết để xác định tính duy nhất. Việc dữ liệu có thể thay đổi hay không là không liên quan. Chỉ có sự độc đáo của các vấn đề hồ sơ. Đó là thiết kế khái niệm của cơ sở dữ liệu.

Khi chúng ta chuyển sang lĩnh vực thực hiện, thì điều an toàn nhất cần làm chỉ đơn giản là sử dụng khóa thay thế.


15

Vâng, theo tôi một khóa chính nên là bất biến.

Ngay cả khi có các khóa ứng viên rõ ràng, tôi luôn sử dụng khóa thay thế. Trong một vài lần tôi đã không làm điều này, tôi gần như luôn hối hận. Và cho dù bạn nghĩ khóa đó bất biến đến mức nào, bạn không thể bảo vệ khỏi các lỗi nhập dữ liệu - nói với người dùng rằng họ không thể chỉnh sửa bit thông tin đó vì đó là khóa chính không đáng buồn.


Điểm hay về lỗi nhập dữ liệu
Tim Goodman

richeym, có vẻ như bạn đang làm cho trường hợp tại sao các khóa KHÔNG phải là bất biến: người dùng có thể muốn thay đổi chúng.
nvogel

4
@dportas - Quan điểm của tôi là tôi thích PK là bất biến nên luôn sử dụng các khóa thay thế ngay cả khi tôi nghĩ có một khóa rõ ràng có thể được lấy từ dữ liệu bảng (ví dụ: email, tên người dùng).
richeym

2

Các cơ chế bộ đệm ở giữa cơ sở dữ liệu và người dùng sẽ mất hiệu quả nếu các khóa chính thay đổi.


2

Tại sao không? Bởi vì bạn muốn loại bỏ một cột?

Chỉ vì các yêu cầu gọi ba cột là duy nhất, không có nghĩa nó phải là khóa chính. Bạn có thể nghĩ rằng quy tắc đó sẽ tồn tại mãi mãi (Hãy nhớ trong cuộc họp đó khi người quản lý bộ phận đầu trọc sẽ không bao giờ thay đổi? Bạn biết đấy, quy tắc vừa bị sa thải.), Nhưng nó sẽ không xảy ra.

Tôi không được trả tiền cho mỗi lần cập nhật theo tầng mà tôi thực hiện và tiền thưởng nếu tôi tự viết mã.

Máy tính không yêu cầu bất kỳ ý nghĩa nào đối với khóa; IMHO, các phím dành cho máy tính, hãy để mọi người làm hỏng phần còn lại của dữ liệu.


1
"Các phím dành cho máy tính, hãy để mọi người làm hỏng phần còn lại của dữ liệu." +1, tốt đẹp.

2

Đó là thực tế không tồi để có một khóa mà giá trị của nó có thể thay đổi.

Các thuộc tính của một khóa tốt bao gồm sự ổn định. Bất biến là lý tưởng nhưng không phải là điều kiện tiên quyết. Giới thiệu một khóa nhân tạo vì lợi ích của sự bất biến là thực tiễn xấu.

Lấy ví dụ về Số Sách Tiêu chuẩn Quốc tế (ISBN) . Nó rất ổn định nhưng không phải là bất biến: đôi khi các nhà xuất bản sách mắc lỗi và - kinh dị! - số trùng lặp có thể xảy ra. Điều này có nghĩa là không nên chấp nhận ISBN làm khóa ứng viên trong cơ sở dữ liệu được vi tính hóa? Tất nhiên là không. Một trong những lợi thế của ISBN là nó có một nguồn đáng tin cậy sẽ giải quyết các vấn đề cho tất cả người dùng trên toàn cầu.

Có một số đặc điểm khác của một khóa tốt, đó là khóa số nguyên tăng tự động vô nghĩa sẽ thiếu, ví dụ như sự quen thuộc (mọi người trong giao dịch sách đều biết hoặc quen thuộc với ISBN), có thể kiểm chứng được (ISBN được in trên tất cả các sách hiện đại), có thể được xác thực bằng tham chiếu đến DBMS (ISBN có chiều rộng cố định và bao gồm tổng kiểm tra), v.v.


3
ISBN là chiều rộng cố định, ngoại trừ khi nó không (xem ISBN-10 so với ISBN-13).
một CVn

Vì vậy, làm thế nào bạn sẽ đề nghị xử lý các mã trùng lặp? Trong tất cả các RDBMS mà tôi biết, bạn sẽ phải có một ràng buộc ĐỘC ĐÁO trên trường để sử dụng nó làm khóa chính.
tự đại diện

1

Tất cả mọi thứ có thể là bất biến nên được. Nó giúp đảm bảo tính chính xác và trợ giúp khi bạn muốn làm cho ứng dụng của mình đa luồng.


1

Có, một khóa chính phải là bất biến, cùng với đó là không rỗng và duy nhất. Tuy nhiên, tôi vẫn chưa tìm thấy một cơ sở dữ liệu thực thi tính bất biến của các khóa chính để bạn có thể tiếp tục và thay đổi giá trị của chúng nếu bạn thực sự muốn.


0

Như một số ý kiến ​​đã nói, một giải pháp là sử dụng khóa chính mới

Ví dụ: (theo ví dụ về @encedaywhen), giả sử tồn tại bảng Sách lưu trữ danh sách sách và chúng tôi đã "sử dụng" để xác định ISBN làm khóa chính. Tuy nhiên, một số tác giả đã phạm sai lầm khi gõ một mã sai vì vậy, họ đã yêu cầu thay đổi mã số, nó liên quan đến các nhiệm vụ tiếp theo:

  • tạo sổ đăng ký mới trong bảng Sách
  • trỏ tất cả các tham chiếu từ ISBN cũ sang ISBN mới. (*)
  • Và cuối cùng, xóa sổ đăng ký cũ khỏi bảng Sách.

(*) điều này có thể không quan trọng để tìm tất cả các tham chiếu cho mô hình cơ sở dữ liệu sử dụng Khóa ngoài nhưng một số mô hình thiếu nó.

Table Books
ISBN  is the primary key
NAME is a simple field.
etc.

Chúng tôi thay đổi nó như là

Table Books
InternalBookId as the primary key
ISBN as a simple field or an indexed field.
NAME is a simple field.
etc.

Trường hợp InternalBookId mới thậm chí có thể là một giá trị tự động.

Nhược điểm về nó:

  • nó thêm một trường mới sử dụng nhiều không gian / tài nguyên hơn.

  • nó có thể yêu cầu viết lại toàn bộ mô hình.

  • mô hình mới có thể ít tự giải thích.

Người chuyên nghiệp

  • Cho phép thay đổi "khóa chính".
  • Cho phép thậm chí thả hoặc tái cấu trúc "khóa chính", ví dụ, để thay đổi Sách thành ISBN-13 đơn giản đến mức bỏ cột cũ hơn và tạo một cột mới

Bảng mới:

Table Books
InternalBookId as the primary key
ISBN13 is a new field.
NAME is a simple field.
etc.
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.