แบบแผนการตั้งชื่อ Foreign Key


152

ฉันเพิ่งเริ่มทำงานกับคีย์ต่างประเทศเป็นครั้งแรกและฉันสงสัยว่าจะมีรูปแบบการตั้งชื่อมาตรฐานที่จะใช้กับพวกเขาหรือไม่?

รับตารางเหล่านี้:

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

ตำแหน่งที่ Tasks มี Notes งานเป็นเจ้าของโดยผู้ใช้และผู้เขียนผู้ใช้ Notes

คีย์ต่างประเทศทั้งสามจะตั้งชื่ออย่างไรในสถานการณ์นี้ หรือมิฉะนั้นก็มีความสำคัญหรือไม่

อัปเดต : คำถามนี้เกี่ยวกับชื่อคีย์ต่างประเทศไม่ใช่ชื่อฟิลด์!


6
หมายเหตุสำหรับผู้อ่าน: แนวทางปฏิบัติที่ดีที่สุดหลายรายการด้านล่างไม่สามารถใช้งานได้ใน Oracle เนื่องจากมีความยาวชื่อได้ไม่เกิน 30 ตัวอักษร ชื่อตารางหรือชื่อคอลัมน์อาจมีความยาวได้ถึง 30 ตัวอักษรดังนั้นแบบแผนที่รวมทั้งสองเป็นชื่อเดียวต้องใช้มาตรฐานการตัดปลายหรือลูกเล่นอื่น ๆ
Charles Burns

คำตอบ:


179

แบบแผนมาตรฐานใน SQL Server คือ:

FK_ForeignKeyTable_PrimaryKeyTable

ตัวอย่างเช่นกุญแจสำคัญระหว่างบันทึกย่อและภารกิจคือ:

FK_note_task

และกุญแจระหว่างงานกับผู้ใช้จะเป็น:

FK_task_user

สิ่งนี้จะช่วยให้คุณเห็นภาพรวมของตารางที่เกี่ยวข้องกับคีย์ดังนั้นจึงทำให้ง่ายต่อการดูว่าตารางใดที่หนึ่ง (เฉพาะชื่อแรก) ขึ้นอยู่กับ (ตารางที่สองชื่อ) ในสถานการณ์นี้ชุดคีย์ที่สมบูรณ์จะเป็น:

FK_task_user
FK_note_task
FK_note_user

ดังนั้นคุณจะเห็นได้ว่างานขึ้นอยู่กับผู้ใช้และโน้ตขึ้นอยู่กับทั้งงานและผู้ใช้


1
หากคีย์ต่างประเทศชี้ไปที่คีย์ตัวเลือกบนตารางที่สองแทนที่จะเป็นคีย์หลักคุณอาจจะใช้ส่วนที่สามกับชื่อเพื่อรับรองคุณสมบัตินี้ เป็นสถานการณ์ที่ผิดปกติที่จะเกิดขึ้นและไม่ใช่สิ่งที่คุณมักจะออกแบบตั้งแต่เริ่มต้นดังนั้นฉันจึงไม่ได้รวมสิ่งนี้ไว้ในการตอบกลับ
Greg Beech

4
คุณรวมชื่อตารางปัจจุบันในคีย์เพื่อให้ชัดเจน ชื่อ FK อยู่ใน namespace ส่วนกลางใน SQL Server ดังนั้นคุณไม่สามารถมี FK สองชื่อ FK_PrimaryKeyTable ที่แนบมากับตารางคีย์ต่างประเทศสองตาราง กฎอาจแตกต่างกันสำหรับเซิร์ฟเวอร์ฐานข้อมูลอื่น ๆ
Greg Beech

ตกลง ... ฉันมีเนมสเปซที่แตกต่างกันสำหรับแต่ละตารางใน Oracle ดังนั้นฉันไม่ต้องการการอ้างอิงตนเอง
Steve Moyer

29
สิ่งนี้ดูเหมือนจะเป็นการใช้งานทั่วไป แต่สิ่งที่ผู้คนต้องทำเมื่อมีคีย์ต่างประเทศสองตัวที่ชี้ไปยังตารางเดียวกัน เช่นmessageตารางมีfrom_user_idและทั้งของคนเหล่านั้นก็จะกลายเป็นto_user_id fk_message_userดูเหมือนว่าฉันจะใช้ดีกว่าfk_tablename_columnname(fk_message_from_user_id ในตัวอย่างของฉัน) ด้วยเหตุผลนี้จากนั้นพยายามทำให้ชื่อคอลัมน์ของคุณชัดเจนเกี่ยวกับตารางเป้าหมาย (เช่น to_user_id อ้างถึงตารางผู้ใช้อย่างชัดเจน)
รหัสผู้บัญชาการ

เกิดอะไรขึ้นถ้าทั้งสองตารางมีขีดเส้นใต้เช่นกัน user_role และ user_addresses fk_user_addresses_user_role มันไม่สับสนใช่ไหม
Govi S

38

ฉันใช้อักขระขีดเส้นใต้สองตัวเป็นตัวคั่นเช่น

fk__ForeignKeyTable__PrimaryKeyTable 

นี่เป็นเพราะชื่อตารางบางครั้งจะมีอักขระขีดเส้นใต้ตัวเอง สิ่งนี้เป็นไปตามหลักการตั้งชื่อสำหรับข้อ จำกัด โดยทั่วไปเนื่องจากชื่อขององค์ประกอบข้อมูลมักจะมีอักขระขีดล่างเช่น

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
นี่คือคำตอบที่ดีที่สุด
Frederik Krautwald

1
ฉันเพิ่งสร้าง Derby DB ด้วยหลักการตั้งชื่อที่เฉพาะเจาะจงมากและอันนี้ที่นี่เป็นส่วนที่อ่านได้และติดตามได้มากที่สุด ขอบคุณ
Anddo

17

แล้วไงFK_TABLENAME_COLUMNNAMEล่ะ

K EEP ฉันทีS Imple S tupid เมื่อใดก็ตามที่เป็นไปได้


20
เนื่องจากเมื่อคุณมีฐานข้อมูลขนาดใหญ่ที่มีคีย์และตารางจำนวนมากและคุณได้รับข้อผิดพลาดระหว่างการอัพเดตสกีมาในซอฟต์แวร์ของคุณมันค่อนข้างยากที่จะหาตำแหน่งที่คีย์ต่างประเทศถูกกำหนดแม้โดยไม่ทำการค้นหาฐานข้อมูลสร้างสคริปต์
JohnC

1
@JohnC หากชื่อคอลัมน์ FK มีชื่อตารางอื่นในชื่อคอลัมน์คุณไม่ควรบอกได้อย่างง่ายดายใช่หรือไม่ มันบอกคุณสองตารางและชื่อคอลัมน์ที่กำหนดไว้ ตัวอย่าง: - FK_Animals_OwnerIDตารางสัตว์และเจ้าของกำหนดไว้ในคอลัมน์ OwnerID
David Sherret

10

หมายเหตุจาก Microsoft เกี่ยวกับ SQL Server:

ข้อ จำกัด ของคีย์ต่างประเทศไม่จำเป็นต้องเชื่อมโยงกับข้อ จำกัด ของคีย์หลักในตารางอื่น มันยังสามารถกำหนดให้อ้างอิงคอลัมน์ของข้อ จำกัด UNIQUE ในตารางอื่น

ดังนั้นฉันจะใช้คำอธิบายการอ้างอิงแทนข้อตกลงความสัมพันธ์หลัก / ความสัมพันธ์ต่างประเทศแบบเดิม

เมื่ออ้างถึงคีย์หลักของตารางอิสระ (พาเรนต์)โดยคอลัมน์ที่มีชื่อคล้ายกันในตาราง(ลูก) ขึ้นอยู่กับว่าฉันละเว้นชื่อคอลัมน์:

FK_ChildTable_ParentTable

เมื่ออ้างอิงคอลัมน์อื่น ๆ หรือชื่อคอลัมน์จะแตกต่างกันระหว่างสองตารางหรือเพียงเพื่อให้ชัดเจน:

FK_ChildTable_childColumn_ParentTable_parentColumn

9

ฉันมักจะปล่อย PK ของฉันชื่อ id แล้วทำการต่อชื่อตารางของฉันและชื่อคอลัมน์คีย์เมื่อตั้งชื่อ FK ในตารางอื่น ๆ ฉันไม่เคยกังวลกับการใส่อูฐเพราะฐานข้อมูลบางตัวทิ้งตัวพิมพ์เล็กและตัวพิมพ์ใหญ่และส่งคืนชื่อตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็กทั้งหมด ไม่ว่าในกรณีใดนี่คือลักษณะของตารางเวอร์ชันของฉันที่จะมีลักษณะ:

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

โปรดทราบว่าฉันยังตั้งชื่อตารางของฉันในเอกพจน์ด้วยเนื่องจากแถวแสดงถึงวัตถุอย่างใดอย่างหนึ่งที่ฉันยังคงอยู่ การประชุมเหล่านี้หลายอย่างเป็นเรื่องส่วนตัว ฉันขอแนะนำว่ามันเป็นสิ่งสำคัญยิ่งกว่าการเลือกการประชุมและใช้มันเสมอกว่าการยอมรับอนุสัญญาของคนอื่น


เฮ้ - นี่คือสไตล์ที่แน่นอนที่ฉันใช้จริง ๆ (แต่มี camelCase) - ฉันคิดว่าฉันจะเพิ่มคำอธิบายเพิ่มเติมเล็กน้อยลงในชื่อเพื่อวัตถุประสงค์ในการอธิบายลิงก์
nickf

อย่างน้อยเราก็สามารถอ่าน schema ของกันและกัน;) ... สิ่งที่น่าอายคือไม่สามารถอ่านของคุณเองได้หลังจากสองสามปีที่ผ่านมา เราใช้ ERWin เพื่อทำแผนผัง schemas ของเรา แต่มักจะสะดวกในการมีเวอร์ชันข้อความและมีแบบแผนให้คุณค้นหาตารางและเขตข้อมูลได้อย่างง่ายดาย
Steve Moyer

5

นี่อาจจะเป็นมากกว่าการฆ่า แต่มันก็ได้ผลสำหรับฉัน มันช่วยฉันได้อย่างมากเมื่อฉันจัดการกับ VLDB โดยเฉพาะอย่างยิ่ง ฉันใช้สิ่งต่อไปนี้:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

แน่นอนถ้าด้วยเหตุผลบางอย่างคุณไม่ได้อ้างอิงคีย์หลักคุณจะต้องอ้างอิงคอลัมน์ที่มีอยู่ในข้อ จำกัด ที่ไม่ซ้ำกันในกรณีนี้:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

มันอาจจะยาวใช่ มันช่วยให้ข้อมูลชัดเจนสำหรับรายงานหรือรับฉันอย่างรวดเร็วว่าปัญหาที่อาจเกิดขึ้นในระหว่างการแจ้งเตือนแยง 100% ชอบที่จะรู้ว่าคนคิดในการประชุมการตั้งชื่อนี้


1

วิธีการปกติของฉันคือ

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

หรือในแง่อื่น ๆ

FK_ChildColumnName_ParentTableName_ParentColumnName

ด้วยวิธีนี้ฉันสามารถตั้งชื่อคีย์ต่างประเทศสองตัวที่อ้างอิงตารางเดียวกันเช่นเดียวhistory_info tableกับกับcolumn actionBy and actionToจากusers_infoตาราง

มันจะเป็นเช่นนั้น

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

โปรดทราบว่า:

ฉันไม่ได้รวมชื่อตารางเด็กเพราะมันเป็นเรื่องธรรมดาสำหรับฉันฉันอยู่ในตารางของเด็กดังนั้นฉันจึงสามารถสมมติชื่อตารางของเด็ก ๆ ได้อย่างง่ายดาย จำนวนตัวอักษรทั้งหมดของมันคือ 26 และเหมาะสมกับความยาวสูงสุด 30 ตัวอักษรของ oracleซึ่ง Charles Burns ระบุไว้ในความคิดเห็นที่นี่

หมายเหตุสำหรับผู้อ่าน: แนวทางปฏิบัติที่ดีที่สุดหลายรายการด้านล่างไม่สามารถใช้งานได้ใน Oracle เนื่องจากมีความยาวชื่อได้ไม่เกิน 30 ตัวอักษร ชื่อตารางหรือชื่อคอลัมน์อาจมีความยาวได้ถึง 30 ตัวอักษรดังนั้นแบบแผนที่รวมทั้งสองเป็นชื่อเดียวต้องใช้มาตรฐานการตัดปลายหรือลูกเล่นอื่น ๆ - ชาร์ลส์เบิร์นส์


หนึ่งของคุณจะล้มเหลวถ้าคุณมีตารางที่ 3 มี FK ชี้ไปที่ ParentTableName_ParentColumnName ตารางเดียวกันโดยซ้ำ FK_Name
โทนี่ดง

0

ตามคำตอบและความคิดเห็นที่นี่แผนการตั้งชื่อซึ่งรวมถึงตาราง FK ฟิลด์ FK และตาราง PK (FK_FKTbl_FKCol_PKTbl) ควรหลีกเลี่ยงการชนชื่อข้อ จำกัด FK

ดังนั้นสำหรับตารางที่กำหนดที่นี่:

fk_task_userid_user
fk_note_userid_user

ดังนั้นหากคุณเพิ่มคอลัมน์เพื่อติดตามผู้ที่แก้ไขงานหรือบันทึกล่าสุด ...

fk_task_modifiedby_user
fk_note_modifiedby_user

-2

หากคุณไม่ได้อ้างอิง FK ของคุณที่ใช้บ่อยและใช้ MySQL (และ InnoDB) คุณสามารถให้ MySQL ตั้งชื่อ FK ให้คุณได้

ในเวลาต่อมาคุณสามารถหาชื่อ FK ที่คุณต้องการโดยการเรียกใช้แบบสอบถาม


4
ฉันสามารถอธิบายการลงคะแนนเสียงของฉันได้เท่านั้น เกือบทุกระบบฐานข้อมูลอนุญาตให้ระบบตั้งชื่อข้อ จำกัด คุณสามารถจินตนาการย้อนกลับไปและพยายามคิดออกอย่างรวดเร็วในระหว่างปัญหาการผลิตที่มีฐานข้อมูลตาราง 100 แม้พยายามที่จะถอดรหัสความสัมพันธ์อะไรที่ FK__123ee456ff เกี่ยวข้อง? มันเป็นเรื่องธรรมดาและเรียบง่าย เมื่อคุณสร้างดัชนีใน FK นี้จะเป็นอย่างไร ชื่อระบบนั้นด้วยหรือไม่ ดังนั้นเมื่อดัชนี IX_007e373f5963 มีการแยกส่วน 98% คุณจะรู้ได้อย่างไรว่าจะหาสาเหตุได้อย่างไร มันไม่ควรทำ
SSISPissesMeOff

-3

ลองใช้ UUID เวอร์ชัน 4 ที่เป็นตัวพิมพ์ใหญ่ด้วย octet แรกแทนที่ด้วย FK และ '_' (ขีดล่าง) แทน '-' (เส้นประ)

เช่น

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

เหตุผลมีดังต่อไปนี้

  • อัลกอริธึมการสร้างแบบเข้มงวด => ชื่อชุด ;
  • ความยาวคีย์น้อยกว่า 30 อักขระซึ่ง จำกัด การตั้งชื่อความยาวใน Oracle (ก่อนหน้า 12c)
  • หากชื่อเอนทิตีของคุณเปลี่ยนแปลงคุณไม่จำเป็นต้องเปลี่ยนชื่อ FK ของคุณในแนวทางตามชื่อเอนทิตี้ (ถ้าฐานข้อมูลรองรับตัวดำเนินการเปลี่ยนชื่อตาราง);
  • จะไม่ค่อยใช้ชื่อข้อ จำกัด ของ foreign key เช่นเครื่องมือฐานข้อมูลมักจะแสดงให้เห็นถึงข้อ จำกัด ที่ใช้ ไม่ต้องกลัวรูปลักษณ์ลึกลับเพราะคุณสามารถหลีกเลี่ยงได้สำหรับ "ถอดรหัส"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.