Sơ đồ đặt tên khóa ngoại


152

Tôi mới bắt đầu làm việc với các khóa ngoại lần đầu tiên và tôi tự hỏi liệu có một sơ đồ đặt tên tiêu chuẩn để sử dụng cho chúng không?

Cho các bảng sau:

task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)

Trong đó Nhiệm vụ có Ghi chú, Nhiệm vụ được sở hữu bởi Người dùng và Ghi chú của tác giả Người dùng.

Làm thế nào ba khóa ngoại được đặt tên trong tình huống này? Hoặc cách khác, nó thậm chí còn quan trọng ?

Cập nhật : Câu hỏi này là về tên khóa nước ngoài, không phải tên trường!


6
Lưu ý cho độc giả: Nhiều cách thực hành tốt nhất được liệt kê dưới đây không hoạt động trong Oracle vì giới hạn tên 30 ký tự của nó. Tên bảng hoặc tên cột có thể đã gần 30 ký tự, do đó, một quy ước kết hợp cả hai thành một tên đòi hỏi một tiêu chuẩn cắt ngắn hoặc các thủ thuật khác.
Charles Burns

Câu trả lời:


179

Quy ước chuẩn trong SQL Server là:

FK_ForeignKeyTable_PrimaryKeyTable

Vì vậy, ví dụ, chìa khóa giữa ghi chú và tác vụ sẽ là:

FK_note_task

Và chìa khóa giữa các tác vụ và người dùng sẽ là:

FK_task_user

Điều này cung cấp cho bạn một cái nhìn 'trong nháy mắt' về việc các bảng có liên quan đến khóa, vì vậy nó giúp dễ dàng xem các bảng cụ thể (bảng đầu tiên được đặt tên) phụ thuộc vào (bảng thứ hai được đặt tên). Trong trường hợp này, bộ khóa hoàn chỉnh sẽ là:

FK_task_user
FK_note_task
FK_note_user

Vì vậy, bạn có thể thấy rằng các tác vụ phụ thuộc vào người dùng và ghi chú phụ thuộc vào cả tác vụ và người dùng.


1
Nếu khóa ngoại trỏ đến khóa ứng viên trên bảng thứ hai chứ không phải khóa chính, thì có lẽ bạn sẽ sử dụng phân đoạn thứ ba cho tên để đủ điều kiện này. Đó là một tình huống bất thường xảy ra, và không phải là một tình huống bạn thường thiết kế từ đầu, vì vậy tôi đã không đưa điều này vào phản hồi.
Greg Beech

4
Bạn bao gồm tên bảng hiện tại trong khóa để giữ cho nó khác biệt. Tên FK nằm trong không gian tên toàn cục trong SQL Server, do đó bạn không thể có hai FK có tên FK_PrimaryKeyTable được gắn vào hai bảng khóa ngoại khác nhau. Các quy tắc có thể khác nhau cho các máy chủ cơ sở dữ liệu khác.
Greg Beech

Được rồi ... Tôi có các không gian tên khác nhau cho mỗi bảng trong Oracle, vì vậy tôi không cần tự tham khảo.
Steve Moyer

29
Đây dường như là cách sử dụng phổ biến nhưng mọi người phải làm gì khi có hai khóa ngoại trỏ vào cùng một bảng. tức là messagebảng có một from_user_idto_user_idcả hai sẽ trở thành fk_message_user. Tôi dường như sử dụng tốt hơn fk_tablename_columnname(fk_message_from_user_id trong ví dụ của tôi) vì lý do này và sau đó cố gắng giữ cho tên cột của bạn rõ ràng về bảng mục tiêu (ví dụ: to_user_id đang đề cập rõ ràng đến bảng người dùng)
Bộ chỉ huy mã

Điều gì xảy ra nếu cả hai bảng có dấu gạch dưới cho ex. user_role và user_addresses? fk_user_addresses_user_role không khó hiểu phải không?
Govi S

38

Tôi sử dụng hai ký tự gạch dưới làm dấu phân cách tức là

fk__ForeignKeyTable__PrimaryKeyTable 

Điều này là do tên bảng đôi khi sẽ chứa chính các ký tự gạch dưới. Điều này tuân theo quy ước đặt tên cho các ràng buộc nói chung vì tên của các thành phần dữ liệu sẽ thường chứa các ký tự gạch dưới, ví dụ:

CREATE TABLE NaturalPersons (
   ...
   person_death_date DATETIME, 
   person_death_reason VARCHAR(30) 
      CONSTRAINT person_death_reason__not_zero_length
         CHECK (DATALENGTH(person_death_reason) > 0), 
   CONSTRAINT person_death_date__person_death_reason__interaction
      CHECK ((person_death_date IS NULL AND person_death_reason IS NULL)
              OR (person_death_date IS NOT NULL AND person_death_reason IS NOT NULL))
        ...

3
Đây hoàn toàn là câu trả lời tốt nhất.
Frederik Krautwald

1
Tôi vừa tạo ra Derby DB với quy ước đặt tên rất cụ thể và cái này ở đây là dễ đọc và dễ theo dõi nhất. Cảm ơn bạn
Anddo

17

Thế còn FK_TABLENAME_COLUMNNAME?

K eep I t S imple S ngu ngốc bất cứ khi nào có thể.


20
Bởi vì khi bạn có một db lớn với rất nhiều khóa và bảng và bạn gặp lỗi trong quá trình cập nhật lược đồ trong phần mềm của mình, thật khó để tìm ra khóa ngoại được xác định mà không cần tìm kiếm tập lệnh tạo cơ sở dữ liệu.
JohnC

1
@JohnC nếu tên cột FK có tên bảng khác trong tên cột thì có nên nói rất dễ không? Nó cho bạn biết hai bảng và tên cột được xác định. Ví dụ: FK_Animals_OwnerIDBảng đối tượng và chủ sở hữu, được xác định trên cột Chủ sở hữu
David Sherret

10

Một lưu ý từ Microsoft liên quan đến SQL Server:

Một ràng buộc KEY NGOẠI TỆ không nhất thiết phải được liên kết với một ràng buộc KEY PRIMARY KEY trong một bảng khác; nó cũng có thể được định nghĩa để tham chiếu các cột của một ràng buộc ĐỘC ĐÁO trong một bảng khác.

vì vậy, tôi sẽ sử dụng các thuật ngữ mô tả sự phụ thuộc thay vì các thuật ngữ quan hệ chính / đối ngoại thông thường.

Khi tham chiếu khóa CHÍNH HÃNG của bảng (cha mẹ) độc lập theo (các) cột có tên tương tự trong bảng phụ thuộc (con) , tôi bỏ qua (các) tên cột:

FK_ChildTable_ParentTable

Khi tham chiếu các cột khác hoặc tên cột khác nhau giữa hai bảng hoặc chỉ rõ ràng:

FK_ChildTable_childColumn_ParentTable_parentColumn

9

Tôi thường chỉ để lại tên PK của mình, sau đó ghép tên bảng và tên cột khóa của mình khi đặt tên FK trong các bảng khác. Tôi không bao giờ bận tâm với vỏ lạc đà, bởi vì một số cơ sở dữ liệu loại bỏ phân biệt chữ hoa chữ thường và chỉ đơn giản trả lại tất cả các tên chữ hoa hoặc chữ thường. Trong mọi trường hợp, đây là phiên bản bảng của tôi trông như thế nào:

task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);

Lưu ý rằng tôi cũng đặt tên các bảng của mình theo số ít, bởi vì một hàng đại diện cho một trong những đối tượng tôi đang tồn tại. Nhiều trong số các quy ước là sở thích cá nhân. Tôi đề nghị rằng điều quan trọng hơn là chọn một quy ước và luôn luôn sử dụng nó, hơn là chấp nhận quy ước của người khác.


heh - đây là phong cách chính xác mà tôi thực sự đang sử dụng (nhưng với camelCase) - Tôi nghĩ rằng tôi đã thêm một chút mô tả bổ sung vào tên cho mục đích minh họa mối liên kết của chúng.
nickf

Vì vậy, ít nhất chúng ta có thể đọc các lược đồ của nhau;) ... những gì ngượng ngùng là không thể đọc được của riêng bạn sau một vài năm vắng mặt. Chúng tôi sử dụng ERWin để lập sơ đồ các lược đồ của chúng tôi, nhưng thường rất thuận tiện khi có phiên bản văn bản và có một quy ước cho phép bạn dễ dàng tìm thấy các bảng và trường.
Steve Moyer

5

Điều này có thể là quá mức, nhưng nó làm việc cho tôi. Nó giúp tôi rất nhiều khi tôi giao dịch với VLDBs đặc biệt. Tôi sử dụng như sau:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

Tất nhiên, nếu vì lý do nào đó bạn không tham chiếu khóa chính, bạn phải tham chiếu một cột có trong một ràng buộc duy nhất, trong trường hợp này:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

Có thể dài, vâng. Nó có giúp giữ thông tin rõ ràng cho các báo cáo hay giúp tôi nhanh chóng biết rằng vấn đề tiềm ẩn là trong một cảnh báo prod 100% rất muốn biết suy nghĩ của mọi người về quy ước đặt tên này.


1

Cách tiếp cận thông thường của tôi là

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

Hay nói cách khác

FK_ChildColumnName_ParentTableName_ParentColumnName

Bằng cách này, tôi có thể đặt tên cho hai khóa ngoại tham chiếu cùng một bảng giống như history_info tablevới một column actionBy and actionTotừ users_infobảng

Nó sẽ giống như

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

Lưu ý rằng:

Tôi không bao gồm tên bảng con vì nó có vẻ thông thường đối với tôi, tôi ở trong bảng của trẻ nên tôi có thể dễ dàng giả sử tên bảng của trẻ. Tổng số ký tự của nó là 26 và phù hợp với giới hạn 30 ký tự của nhà tiên tri được Charles Burns nêu trong một nhận xét ở đây

Lưu ý cho độc giả: Nhiều cách thực hành tốt nhất được liệt kê dưới đây không hoạt động trong Oracle vì giới hạn tên 30 ký tự của nó. Tên bảng hoặc tên cột có thể đã gần 30 ký tự, do đó, một quy ước kết hợp cả hai thành một tên đòi hỏi một tiêu chuẩn cắt ngắn hoặc các thủ thuật khác. - Charles Burns


Bảng của bạn sẽ không thành công nếu bạn có bảng thứ 3 có điểm FK tới ParentTableName_ParentColumnName cùng bảng bằng cách sao chép FK_Name
Tony Dong

0

Dựa trên các câu trả lời và nhận xét ở đây, quy ước đặt tên bao gồm bảng FK, trường FK và bảng PK (FK_FKTbl_FKCol_PKTbl) nên tránh xung đột tên ràng buộc FK.

Vì vậy, đối với các bảng đã cho ở đây:

fk_task_userid_user
fk_note_userid_user

Vì vậy, nếu bạn thêm một cột để theo dõi ai đã sửa đổi lần cuối một tác vụ hoặc ghi chú ...

fk_task_modifiedby_user
fk_note_modifiedby_user

-2

Nếu bạn không thường xuyên tham khảo FK của mình và sử dụng MySQL (và InnoDB) thì bạn có thể để MySQL đặt tên FK cho bạn.

Sau đó, bạn có thể tìm thấy tên FK bạn cần bằng cách chạy truy vấn .


4
Tôi chỉ có thể giải thích bỏ phiếu của tôi. Gần như mọi hệ thống cơ sở dữ liệu đều cho phép hệ thống đặt tên cho các ràng buộc, Bạn có thể tưởng tượng việc quay lại và cố gắng nhanh chóng tìm ra vấn đề sản xuất với cơ sở dữ liệu 100 bảng hay không, cố gắng giải mã mối quan hệ FK__123ee456ff liên quan đến vấn đề gì? Nó là đơn giản và chỉ đơn giản là đặt một thực hành HORRIBLE. Khi bạn xây dựng một chỉ mục trên FK này thì sao? Tên hệ thống cũng vậy? Vì vậy, khi chỉ số IX_007e373f5963 bị phân mảnh 98%, làm thế nào bạn sẽ biết nơi để tìm hiểu tại sao? Nó chỉ không nên được thực hiện.
SSISPissesMe Tắt

-3

Hãy thử sử dụng UUID Phiên bản 4 có chữ hoa với octet đầu tiên được thay thế bằng FK và '_' (gạch dưới) thay vì '-' (dấu gạch ngang).

Ví dụ

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

Lý do là như sau

  • Thuật toán tạo nghiêm ngặt => tên thống nhất ;
  • Độ dài khóa nhỏ hơn 30 ký tự , đó là giới hạn độ dài đặt tên trong Oracle (trước 12c);
  • Nếu tên thực thể của bạn thay đổi, bạn không cần đổi tên FK của mình như trong cách tiếp cận dựa trên tên thực thể (nếu DB hỗ trợ toán tử đổi tên bảng);
  • Người ta sẽ hiếm khi sử dụng tên của ràng buộc khóa ngoại. Ví dụ, công cụ DB thường hiển thị những gì ràng buộc áp dụng cho. Không cần phải sợ cái nhìn khó hiểu, bởi vì bạn có thể tránh sử dụng nó để "giải mã".
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.