การตั้งชื่อคอลัมน์ ID ในตารางฐานข้อมูล


101

ฉันสงสัยความคิดเห็นของผู้คนเกี่ยวกับการตั้งชื่อคอลัมน์ ID ในตารางฐานข้อมูล

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

ที่ฉันทำงานปัจจุบันพวกเขาได้เรียก ID คอลัมน์ ID ทั้งหมด

ดังนั้นพวกเขาจะทำสิ่งต่อไปนี้:

Select  
    i.ID 
,   il.ID 
From
    Invoices i
    Left Join InvoiceLines il
        on i.ID = il.InvoiceID

ตอนนี้ฉันพบปัญหาบางประการที่นี่:
1. คุณจะต้องใช้นามแฝงคอลัมน์ใน select
2. ID = InvoiceID ไม่พอดีกับสมองของฉัน
3. ถ้าคุณไม่ได้ใช้นามแฝงตารางและอ้างถึง InvoiceID จะเห็นได้ชัดว่าตารางใด มันอยู่?

คนอื่น ๆ คิดอย่างไรในหัวข้อนี้?



คำตอบ:


29

ID คือ SQL Antipattern ดูhttp://www.amazon.com/s/ref=nb_sb_ss_i_1_5?url=search-alias%3Dstripbooks&field-keywords=sql+antipatterns&sprefix=sql+a

หากคุณมีตารางจำนวนมากที่มี ID เป็น ID คุณจะทำให้การรายงานนั้นยากขึ้นมาก มันบดบังความหมายและทำให้ข้อความค้นหาที่ซับซ้อนอ่านยากขึ้นรวมทั้งกำหนดให้คุณต้องใช้นามแฝงเพื่อแยกความแตกต่างของรายงาน

นอกจากนี้หากมีคนโง่พอที่จะใช้การเข้าร่วมตามธรรมชาติในฐานข้อมูลที่มีอยู่คุณจะเข้าร่วมในบันทึกที่ไม่ถูกต้อง

หากคุณต้องการใช้ไวยากรณ์ USING ที่ dbs บางตัวอนุญาตคุณจะทำไม่ได้หากคุณใช้ ID

หากคุณใช้ ID คุณสามารถลงท้ายด้วยการเข้าร่วมที่ผิดพลาดได้อย่างง่ายดายหากคุณกำลังคัดลอกไวยากรณ์การเข้าร่วม (อย่าบอกนะว่าไม่มีใครเคยทำแบบนี้!) และลืมเปลี่ยนนามแฝงในเงื่อนไขการเข้าร่วม

ตอนนี้คุณมี

select t1.field1, t2.field2, t3.field3
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t1.id = t3.table2id

เมื่อคุณหมายถึง

select t1.field1, t2.field2, t3.field3 
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t2.id = t3.table2id

หากคุณใช้ tablenameID เป็นช่อง id ความผิดพลาดโดยไม่ได้ตั้งใจประเภทนี้มีโอกาสน้อยที่จะเกิดขึ้นมากและค้นหาได้ง่ายกว่ามาก


8
@ spencer7593 เพียงเพราะคุณชอบ ID ไม่ได้หมายความว่าไม่ใช่แอนตี้แพตเทิร์น เป็นการยากที่จะทำผิดพลาดในการรวมเมื่อคุณมีรหัสชื่อตารางเนื่องจากคุณจะได้รับข้อผิดพลาดทางไวยากรณ์ทันที
HLGEM

7
+1 คอลัมน์ที่มีความหมายเหมือนกันควรมีชื่อเดียวกันโดยใช้คำนำหน้าชื่อตารางคุณสามารถมีคอลัมน์คีย์หลักชื่อ table1ID และคอลัมน์คีย์ต่างประเทศในตารางอื่นที่เรียกว่า table1ID - และคุณรู้ว่าเป็นสิ่งเดียวกัน ฉันได้รับการสอนเรื่องนี้เมื่อ 20 ปีที่แล้วและเป็นการฝึกฝนที่ไม่ทำให้คุณผิดหวัง
amelvin

10
ไม่! นี่คือหลักการตั้งชื่อสเมิร์ฟ!
รอส

20
ฉันไม่ชอบหลักการนี้เพราะมันหมายความว่าคุณถูกบังคับให้ใช้นามแฝงในตารางทั้งหมดของคุณเพื่อที่คุณจะได้ไม่ต้องตั้งชื่อตารางซ้ำซ้อนตั้งชื่อตารางอีกครั้งแล้วจึงเพิ่มรหัส join table2 on table1.table1id = table2.table1id. เหตุผลของคุณก็โอเคยกเว้นว่าถ้าคุณใช้ id ชื่อของตารางจะอยู่หน้า ID อยู่ดี join table2 on table1.id = table2.table1id... ซึ่งเป็นเพียงรายละเอียดและไม่ซ้ำซ้อนหรือบังคับใช้นามแฝงที่คลุมเครือเพื่อป้องกันความซ้ำซ้อนที่กล่าวถึง .. ซึ่งในความคิดของฉันเป็นสารพิษของการพัฒนา sql
Anther

15
ถ้าคุณมีNameฟิลด์ในตารางคุณควรเปลี่ยนเป็นTable1Nameเพื่อหลีกเลี่ยงปัญหาเดียวกันกับฟิลด์นั้นหรือไม่? คุณควรนำหน้าคอลัมน์ทั้งหมดด้วยชื่อตารางด้วยเหตุผลเดียวกันหรือไม่ ฟังดูไม่ถูกต้อง
Joanvo

154

ฉันมักจะชอบ ID เป็น TableName + ID สำหรับคอลัมน์ id จากนั้น TableName + ID สำหรับคีย์ต่างประเทศ ด้วยวิธีนี้ตารางทั้งหมดจะมีชื่อเดียวกันสำหรับฟิลด์ id และไม่มีคำอธิบายซ้ำซ้อน ดูเหมือนว่าจะง่ายกว่าสำหรับฉันเพราะตารางทั้งหมดมีชื่อฟิลด์คีย์หลักเหมือนกัน

เท่าที่เข้าร่วมตารางและไม่ทราบว่าฟิลด์ Id ใดเป็นของตารางใดในความคิดของฉันควรเขียนแบบสอบถามเพื่อจัดการกับสถานการณ์นี้ ฉันทำงานที่ไหนเรามักจะกำหนดฟิลด์ที่เราใช้ในคำสั่งด้วยนามแฝง table / table


2
ฉันรู้ว่ามีกระทู้เก่า แต่ฉันเห็นด้วย ยังทำให้การแมปที่ชั้น dataaccess ง่ายขึ้น: ถ้า "ออบเจ็กต์" ทั้งหมดมีฟิลด์ Id ที่ต้องไม่ซ้ำกันเมื่อสร้างเมธอดในชั้นการเข้าถึงข้อมูลเพื่อทำสิ่งต่างๆเช่นลบรายการคุณสามารถทำให้เป็นแบบทั่วไปได้เนื่องจากคุณสามารถรับรายการ รหัสสำหรับอะไรก็ได้และรู้ว่าคุณเพียงแค่ต้องลบโดยที่ Id = blah ออกจากตารางนั้นแทนที่จะต้องทำการแมปสิ่งที่ไม่ซ้ำกันสำหรับแต่ละตารางตลอดจนการแมปชื่อตาราง / ชื่อตรรกะของโปรแกรม
Mike

1
เควินเช่นเดียวกับคุณ ตัวอย่างเช่น user_id, role_id สำหรับ PKey และ role_user_id สำหรับ FKey เป็นสิ่งที่ดีสำหรับโครงการขนาดใหญ่ เนื่องจากถ้าฟิลด์ ID ทั้งหมดตั้งชื่อเป็น "id" จะทำให้สับสนเกินไป แต่ฉันคิดว่ามันเป็นความชอบส่วนบุคคลบางคนคิดว่าแค่ใช้ "id" เท่านั้นที่ชัดเจน
Cheung

2
นี่คือความชอบของฉัน เพียงเพราะการสืบค้นข้ามตารางอ่านยากกว่าไม่ได้หมายความว่าควรเปลี่ยนคอลัมน์ Id เพื่อให้ง่ายขึ้น เพียงแค่ทำให้นามแฝงของคุณสื่อความหมายได้มากขึ้น
tmutton

1
ฉันสงสัยว่ารูปแบบของการนำหน้า ID ที่มีชื่อเอนทิตีมาจากผู้ที่ใช้ "เลือก * จาก" ไม่ว่าด้วยเหตุผลใดก็ตาม ในสภาพแวดล้อมที่ทนต่อการ "เลือก *" ได้ความเป็นจริงมักจะบิดเบือนไปสู่การสนับสนุนการเลือกทุกอย่างจำนวนมากจากทุกที่ ไม่สมเหตุสมผลถ้าคุณไม่เลือกทุกอย่างสุ่มสี่สุ่มห้า นอกจากนี้ยังมีการอ้างอิงถึงการใช้และการรวมตามธรรมชาติซึ่งค่อนข้างอันตรายและดูเหมือนจะไม่เป็นการโต้แย้งสำหรับฉันเลยเพราะมันป้องกันไม่ให้คุณใช้หลักการตั้งชื่อคีย์ต่างประเทศตามบทบาทได้อย่างมีประสิทธิภาพ
Roman Polunin

53

มีการต่อสู้ที่น่าเบื่อเกี่ยวกับสิ่งนี้ใน บริษัท ของฉันในช่วงปลายปี การถือกำเนิดของ LINQ ทำให้รูปแบบtablename + IDซ้ำซ้อนยิ่งดูโง่ลงไปอีกในสายตาของฉัน ฉันคิดว่าคนที่มีเหตุผลส่วนใหญ่จะบอกว่าถ้าคุณเขียน SQL ด้วยมือในลักษณะที่คุณต้องระบุชื่อตารางเพื่อแยกความแตกต่างของFKไม่ใช่แค่การประหยัดในการพิมพ์เท่านั้น แต่ยังเพิ่มความชัดเจนให้กับ SQL ของคุณในการใช้งาน ID ในนั้นคุณสามารถเห็นได้อย่างชัดเจนว่าคือPKและFKใด

เช่น

จากพนักงาน e LEFT JOIN ลูกค้า c ON e.ID = c.EmployeeID

บอกฉันไม่เพียงว่าทั้งสองเชื่อมโยงกัน แต่คือPKและFKใด ในขณะที่รูปแบบเก่าคุณถูกบังคับให้มองหรือหวังว่าพวกเขาจะได้รับการตั้งชื่อที่ดี


2
ยกเว้นฉันไม่เคยรู้จักนักพัฒนาคนเดียวในชีวิตเพื่อเขียนตัวอย่างของคุณ พวกเขาเขียนแทน: LEFT JOIN ลูกค้าเป็น c ON e.ID = c.EmployeeID สำหรับฉันแล้วสิ่งนี้ชัดเจนกว่า: LEFT JOIN ลูกค้าเป็น c ON e.EmployeeID = c.EmployeeID และรายการใดที่เป็น Foreign Key ที่ชัดเจนโดยชื่อตาราง . เห็นได้ชัดว่า customer.employeeId เป็นคีย์ต่างประเทศในขณะที่พนักงาน EmployeeId ไม่ใช่
dallin

8
จำนวนคน (เช่นผู้เขียนรายงานที่เขียน sql ที่ซับซ้อนมาก) และผู้เชี่ยวชาญ BI ที่ทำการนำเข้าและส่งออกยังคงต้องเขียน SQl ด้วยลายมือ การออกแบบฐานข้อมูลต้องรองรับไม่เพียง แต่นักพัฒนาแอปพลิเคชันเท่านั้น
HLGEM

30

เราใช้ไม่ได้InvoiceID IDมันทำให้คำสั่งที่สามารถอ่านได้มากขึ้น - เมื่อคุณเห็นคนเดียวมันอาจจะหมายถึงอะไรโดยเฉพาะอย่างยิ่งเมื่อคุณนามแฝงตารางไปIDi


เห็นด้วยและคุณชี้ให้เห็นเหตุผลหลักที่ไม่ใช้ "id" เพราะเรามักจะมีนามแฝงของตารางเช่น "i" สำหรับ inoice, p สำหรับ "product" บน SQL หรือ LINQ เป็นต้น
Cheung

4
การใช้ Id จะเหมาะสมกว่า คอลัมน์นี้อยู่ในตาราง "ใบแจ้งหนี้" ซึ่งก็น่าจะเพียงพอแล้ว หากคุณกำลังเขียนแบบสอบถามข้ามตารางคุณควรใช้นามแฝงที่สื่อความหมายได้ดีกว่า "ฉัน" ไม่เพียงพอ เรียกว่า "ใบแจ้งหนี้"
tmutton

1
ไม่ชัดเจนว่า "ID" เพียงอย่างเดียวหมายถึงใบแจ้งหนี้ สมมติว่าคุณมีคีย์ต่างประเทศสำหรับบัญชีและบุคคลด้วย ตอนนี้อันไหนคือ "ID" ไม่ง่ายกว่าในการเข้าร่วมพูดอ่าน a.InvoiceID = b.InvoiceID แทนที่จะเป็น a.ID = b.InvoiceID และไม่สามารถดีบักได้อย่างง่ายดาย
Jason Cohen

3
@JasonCohen นี่หมายความว่านามแฝงของตารางเป็นขยะไม่ใช่ชื่อคอลัมน์
Joshua Schlichting

23

ฉันเห็นด้วยกับ Keven และคนอื่น ๆ อีกสองสามคนที่นี่ว่า PK สำหรับตารางควรเป็น Id และคีย์ต่างประเทศแสดงรายการ OtherTable + Id

อย่างไรก็ตามฉันต้องการเพิ่มเหตุผลหนึ่งข้อที่เพิ่งให้น้ำหนักกับข้อโต้แย้งนี้มากขึ้น

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

เพียงแค่อาหารสำหรับความคิด


8
+1 สำหรับตัวอย่างโลกแห่งความเป็นจริงว่าการตั้งชื่อทั่วไปช่วยปรับปรุงการใช้โค้ดซ้ำในบางกรณีได้อย่างไร (ซึ่งนักพัฒนาจำนวนมากจะให้ความสำคัญเนื่องจากมี. NET devs หลายล้านตัวและหลายคนจะใช้ EF)
codingoutloud

ไม่ใช่แค่ EF และสิ่งที่ชอบในงานของฉันเรามีวิธีการทั่วไปมากมาย ดังนั้นบริการเว็บจะมีบางอย่างเช่นรายการ <ผลลัพธ์> บันทึก <T> (รายการ <int> รหัส); เนื่องจากเราทราบดีว่าทุกตารางมีคอลัมน์ Id ที่เป็นคีย์หลักเราจึงสามารถทำสิ่งต่างๆเช่นนี้ได้เพียงแค่การแมปวัตถุ C # กับตาราง (เช่น <Customer, "Customers">, <BillingCode, "BillingCodes"> ( หรือดีกว่า แต่เก็บไว้ในชื่อ proc) สร้าง sql ได้ทันทีตามวัตถุที่ส่งผ่านและไม่มีวิธีบันทึก / ลบ / แก้ไขซ้ำสำหรับวัตถุแต่ละประเภท
Mike

11

ค่ากำหนดของฉันยังเป็น ID สำหรับคีย์หลักและ TableNameID สำหรับคีย์ต่างประเทศ ฉันชอบที่จะมีคอลัมน์ "ชื่อ" ในตารางส่วนใหญ่ที่ฉันถือตัวระบุที่ผู้ใช้อ่านได้ (เช่นชื่อ :-)) ของรายการ โครงสร้างนี้มีความยืดหยุ่นสูงในแอปพลิเคชันเองฉันสามารถจัดการตารางเป็นจำนวนมากได้ในลักษณะเดียวกัน นี่เป็นสิ่งที่ทรงพลังมาก โดยปกติซอฟต์แวร์ OO จะถูกสร้างขึ้นที่ด้านบนของฐานข้อมูล แต่ไม่สามารถใช้ชุดเครื่องมือ OO ได้เนื่องจากฐานข้อมูลไม่อนุญาต การมี ID คอลัมน์และชื่อยังทำได้ไม่ดีนัก แต่เป็นขั้นตอน

เลือก
i.ID, il.ID จากใบแจ้งหนี้ i Left Join InvoiceLines il บน i.ID = il.InvoiceID

ทำไมฉันทำสิ่งนี้ไม่ได้

Select  
    Invoices.ID 
,   InvoiceLines.ID 
From
    Invoices
    Left Join InvoiceLines
        on Invoices.ID = InvoiceLines.InvoiceID

ในความคิดของฉันสิ่งนี้สามารถอ่านได้และเรียบง่ายมาก การตั้งชื่อตัวแปรเป็น i และ il เป็นทางเลือกที่ไม่ดีโดยทั่วไป


10

ไม่สำคัญจริงๆคุณมีแนวโน้มที่จะประสบปัญหาแบบจำลองในรูปแบบการตั้งชื่อทั้งหมด

แต่สิ่งสำคัญคือต้องมีความสอดคล้องกันเพื่อที่คุณจะได้ไม่ต้องดูคำจำกัดความของตารางทุกครั้งที่คุณเขียนแบบสอบถาม


8

ฉันเพิ่งเริ่มทำงานในสถานที่ที่ใช้เฉพาะ "ID" (ในตารางหลักอ้างอิงโดย TableNameID ในคีย์ต่างประเทศ) และพบปัญหาในการผลิตโดยตรงสองรายการที่เกิดจากมัน

ในกรณีหนึ่งแบบสอบถามใช้ "... โดยที่ ID ใน (SELECT ID FROM OtherTable ... " แทน "... โดยที่ ID in (SELECT TransID FROM OtherTable ... "

ใครสามารถพูดได้อย่างตรงไปตรงมาว่าจะไม่ง่ายไปกว่านี้ที่จะระบุว่ามีการใช้ชื่อเต็มและสอดคล้องกันซึ่งข้อความที่ผิดจะอ่าน "... โดยที่ TransID ใน (SELECT OtherTableID จาก OtherTable ... " ฉันไม่คิดว่า ดังนั้น.

ปัญหาอื่น ๆ เกิดขึ้นเมื่อทำการ refactoring รหัส หากคุณใช้ตารางชั่วคราวในขณะที่ก่อนหน้านี้คิวรีออกไปจากตารางหลักโค้ดเก่าจะอ่าน "... dbo.MyFunction (t.ID) ... " และหากไม่มีการเปลี่ยนแปลง แต่ตอนนี้ "t" หมายถึง a ตารางชั่วคราวแทนที่จะเป็นตารางหลักคุณจะไม่ได้รับข้อผิดพลาด - เป็นเพียงผลลัพธ์ที่ผิดพลาด

หากการสร้างข้อผิดพลาดที่ไม่จำเป็นเป็นเป้าหมาย (อาจมีบางคนทำงานไม่เพียงพอ?) หลักการตั้งชื่อแบบนี้ก็ยอดเยี่ยม มิฉะนั้นการตั้งชื่อที่สอดคล้องกันเป็นวิธีที่จะไป


3
+1 สำหรับตัวอย่างโลกแห่งความจริงของชื่อที่เฉพาะเจาะจงมากขึ้นในการปรับปรุงการบำรุงรักษา
codingoutloud

6

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


6

ผมเองชอบ (ตามที่ได้รับการระบุไว้ข้างต้น) เดอะTable.IDสำหรับPKและรหัสตารางสำหรับFK แม้ (โปรดอย่ายิงฉัน) Microsoft Access แนะนำสิ่งนี้

อย่างไรก็ตามฉันยังรู้ด้วยว่าเครื่องมือสร้างบางตัวชอบ TableID สำหรับ PK เพราะพวกเขามักจะเชื่อมโยงชื่อคอลัมน์ทั้งหมดที่มี'ID'ในคำนั้นรวมถึง ID !!!

แม้แต่ตัวออกแบบคิวรีก็ทำเช่นนี้บน Microsoft SQL Server (และสำหรับแต่ละคิวรีที่คุณสร้างคุณจะต้องริปความสัมพันธ์ที่สร้างขึ้นใหม่ที่ไม่จำเป็นทั้งหมดบนตารางทั้งหมดใน ID คอลัมน์)

ดังนั้นเท่าที่เกลียดโรคภายในของฉันมันผมม้วนกับรหัสตารางการประชุม จำไว้ว่ามันเรียกว่า Data BASEเพราะมันจะเป็นฐานสำหรับหวังว่าจะมีแอพพลิเคชั่นมากมายที่จะมา และเทคโนโลยีทั้งหมดควรได้รับประโยชน์จาก Schema ที่เป็นมาตรฐานพร้อมคำอธิบายที่ชัดเจน

มันไปโดยไม่บอกว่าฉันวาดเส้นของฉันเมื่อผู้คนเริ่มใช้ TableName, TableDescription และอื่น ๆ ในความคิดของฉันการประชุมควรดำเนินการดังต่อไปนี้:

  • ชื่อตาราง: พหูพจน์ เช่น พนักงาน
  • นามแฝงของตาราง: ชื่อเต็มตารางเอกพจน์ เช่น

    SELECT Employee.*, eMail.Address
    FROM Employees AS Employee LEFT JOIN eMails as eMail on Employee.eMailID = eMail.eMailID -- I would sure like it to just have the eMail.ID here.... but oh well
    

[อัปเดต]

นอกจากนี้ยังมีโพสต์ที่ถูกต้องในชุดข้อความนี้เกี่ยวกับคอลัมน์ที่ซ้ำกันเนื่องจาก "ประเภทของความสัมพันธ์" หรือบทบาท ตัวอย่างเช่นหากร้านค้ามีรหัสพนักงานที่บอกว่าหมอบ ดังนั้นบางครั้งผมทำสิ่งที่ชอบStore.EmployeeID_Manager แน่นอนว่ามันใหญ่กว่าเล็กน้อย แต่ในทางกลับกันผู้คนจะไม่คลั่งไคล้ในการค้นหาTable ManagerIDหรือสิ่งที่EmployeeIDกำลังทำอยู่ที่นั่น เมื่อการสอบถามคือ WHERE ฉันจะทำให้มันง่ายขึ้นเช่น: SELECT EmployeeID_Manager เป็น ManagerID จาก Store


ฉันคิดว่าประเด็นของคุณดีสำหรับความสวยงามของฐานข้อมูลและจุดประสงค์ด้านการสอน แต่สำหรับฟังก์ชันการทำงานฉันคิดว่าเป็นปัญหา ชื่อตารางพหูพจน์ส่งเสริมความไม่สอดคล้องกันระหว่างตารางและรหัส PK <-> FK IdTable สร้างความแตกต่างในชื่อของสิ่งเดียวกัน ในขณะเดียวกันสิ่งที่ชอบUser.UserIdก็แปลกที่จะพิมพ์ในการเขียนโปรแกรม
Machado

4

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

เห็นได้ชัดว่าหลักการตั้งชื่อเป็นเรื่องส่วนตัวและเป็นเรื่องของรูปแบบ ฉันพบแนวทาง ISO / IEC 11179 เพื่อเป็นจุดเริ่มต้นที่มีประโยชน์

สำหรับ DBMS ที่ฉันเห็นตารางเป็นคอลเลกชันของ entites (ยกเว้นผู้ที่เคยมีหนึ่งแถวเช่น cofig ตารางตารางของค่าคงที่, ฯลฯ ) เช่นโต๊ะที่ฉันเป็นกุญแจสำคัญจะได้รับการตั้งชื่อemployee_ID PersonnelตรงไปตรงมาการTableNameIDประชุมไม่ได้ผลสำหรับฉัน

ฉันเคยเห็นTableName.ID=PK TableNameID=FKรูปแบบที่ใช้กับแบบจำลองข้อมูลขนาดใหญ่และต้องบอกว่าฉันรู้สึกสับสนเล็กน้อย: ฉันชอบที่ชื่อตัวระบุจะเหมือนกันมากตลอดเช่นไม่เปลี่ยนชื่อตามตารางที่ปรากฏขึ้นสิ่งที่ควรทราบคือ รูปแบบดังกล่าวดูเหมือนจะถูกใช้ในร้านค้าที่เพิ่มIDENTITYคอลัมน์ (เพิ่มขึ้นอัตโนมัติ) ให้กับทุกโต๊ะในขณะที่ใช้คีย์ธรรมชาติและคีย์ผสมในคีย์ต่างประเทศ ร้านค้าเหล่านั้นมักจะไม่มีพจนานุกรมข้อมูลที่เป็นทางการหรือสร้างจากโมเดลข้อมูล อีกครั้งนี่เป็นเพียงคำถามเกี่ยวกับสไตล์และเป็นคำถามที่ฉันไม่ได้สมัครเป็นสมาชิกเป็นการส่วนตัว ท้ายที่สุดแล้วมันไม่ใช่สำหรับฉัน

ทั้งหมดที่กล่าวมาฉันสามารถเห็นกรณีที่บางครั้งทิ้ง qualifier จากชื่อคอลัมน์เมื่อชื่อตารางให้บริบทสำหรับการทำเช่นนั้นเช่นองค์ประกอบที่มีชื่อemployee_last_nameอาจกลายเป็นเพียงแค่last_nameในPersonnelตาราง เหตุผลก็คือโดเมนคือ 'นามสกุลของผู้ใช้' และมีแนวโน้มที่จะถูกUNIONแก้ไขด้วยlast_nameคอลัมน์จากตารางอื่นมากกว่าที่จะใช้เป็นคีย์ต่างประเทศในตารางอื่น แต่แล้วอีกครั้ง ... ฉันอาจจะเปลี่ยนใจ บางครั้งคุณไม่สามารถบอกได้ นั่นคือสิ่งที่: การสร้างแบบจำลองข้อมูลเป็นศิลปะส่วนหนึ่งวิทยาศาสตร์ส่วนหนึ่ง


2

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

สิ่งที่ฉันหมายถึงในคำสั่งแรกคือแทนที่จะใช้ ID คุณสามารถใช้อย่างอื่นเช่น 'recno' ดังนั้นตารางนี้จะมี PK เป็น invoice_recno เป็นต้น

ไชโยเบ็น


2

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

 Select Invoice.InvoiceID, Lines.InvoiceLine, Customer.OrgName
 From Invoices Invoice
 Join InvoiceLines Lines on Lines.InvoiceID = Invoice.InvoiceID
 Join Customers Customer on Customer.CustomerID = Invoice.CustomerID

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


1

สำหรับชื่อคอลัมน์ในฐานข้อมูลฉันจะใช้ "InvoiceID"

หากฉันคัดลอกช่องไปยังโครงสร้างที่ไม่มีชื่อผ่าน LINQ ฉันอาจตั้งชื่อว่า "ID" ที่นั่นหากเป็น ID เดียวในโครงสร้าง

ถ้าจะไม่ใช้คอลัมน์นี้ในคีย์นอกดังนั้นจะใช้เพื่อระบุแถวที่ไม่ซ้ำกันสำหรับการแก้ไขการแก้ไขหรือการลบฉันจะตั้งชื่อว่า "PK"


1

หากคุณตั้งชื่อที่ไม่ซ้ำกันให้กับคีย์แต่ละรายการเช่น "invoice.invoice_id" แทน "invoice.id" คุณสามารถใช้โอเปอเรเตอร์ "natural join" และ "using" ได้โดยไม่ต้องกังวล เช่น

SELECT * FROM invoices NATURAL JOIN invoice_lines
SELECT * FROM invoices JOIN invoice_lines USING (invoice_id)

แทน

SELECT * from invoices JOIN invoice_lines
    ON invoices.id = invoice_lines.invoice_id

SQL มีรายละเอียดเพียงพอโดยไม่ต้องทำให้ละเอียดมากขึ้น


คุณรู้หรือไม่ว่า SQL Server รองรับการรวมแบบธรรมชาติหรือไม่?
Arry

ฉันไม่คิดว่ามันจะ อ้างอิงจากconnect.microsoft.com/SQLServer/feedback/…ปรากฏว่ามีกำหนดให้เพิ่มไวยากรณ์ในบางเวอร์ชันหลังจาก SQL Server 2005 ฉันรู้ว่ามันใช้ได้ใน PostgreSQL และใน Oracle
Steven Huwig

7
ไม่เคยไม่ใช้การเข้าร่วมตามธรรมชาติ ถ้าตารางหนึ่งมีฟิลด์คำอธิบายเมื่อคุณเขียนแบบสอบถามคุณก็สบายดี หากในภายหลังมีคนเพิ่มฟิลด์คำอธิบายลงในตารางอื่นคุณจะเริ่มเข้าร่วมในตารางนั้นเช่นกันและหยุดทำงานโดยสิ้นเชิง

1
เฮ้นั่นฟังดูเหมือนประสบการณ์ในชีวิตจริง :)
dland

ฉันจะใช้การเข้าร่วมตามธรรมชาติสำหรับการค้นหาเฉพาะกิจเท่านั้น
Steven Huwig

1

สิ่งที่ฉันทำเพื่อให้สิ่งที่สอดคล้องกันสำหรับตัวเอง (ที่ตารางมีคอลัมน์เดียวคีย์หลักที่ใช้เป็นรหัส) Table_pkคือการตั้งชื่อคีย์หลักของตาราง ทุกที่ที่มีคีย์ต่างประเทศที่ชี้ไปที่คีย์หลักของตารางนั้นฉันเรียกคอลัมน์PrimaryKeyTable_fkนั้น ด้วยวิธีนี้ฉันรู้ว่าถ้าฉันมีCustomer_pkในตารางลูกค้าและCustomer_fkในตารางคำสั่งซื้อของฉันฉันรู้ว่าตารางใบสั่งซื้อหมายถึงรายการในตารางลูกค้า

สำหรับฉันแล้วสิ่งนี้สมเหตุสมผลโดยเฉพาะอย่างยิ่งสำหรับการเข้าร่วมที่ฉันคิดว่ามันอ่านง่ายกว่า

SELECT * 
FROM Customer AS c
    INNER JOIN Order AS c ON c.Customer_pk = o.Customer_fk

1

FWIW มาตรฐานใหม่ของเรา (ซึ่งมีการเปลี่ยนแปลงเอ่อฉันหมายถึง "วิวัฒนาการ" ในทุกโครงการใหม่) คือ:

  • ชื่อฟิลด์ฐานข้อมูลตัวพิมพ์เล็ก
  • ชื่อตารางตัวพิมพ์ใหญ่
  • ใช้เครื่องหมายขีดล่างเพื่อแยกคำในชื่อฟิลด์ - แปลงคำเหล่านี้เป็นตัวอักษร Pascal ในรหัส
  • pk_ คำนำหน้าหมายถึงคีย์หลัก
  • _id คำต่อท้ายหมายถึงจำนวนเต็มรหัสการเพิ่มอัตโนมัติ
  • fk_ คำนำหน้าหมายถึงคีย์ต่างประเทศ (ไม่จำเป็นต้องต่อท้าย)
  • _VW คำต่อท้ายสำหรับการดู
  • is_ คำนำหน้าสำหรับบูลีน

ดังนั้นตารางชื่อ NAMES อาจมีฟิลด์pk_name_id, first_name, last_name, is_alive,และfk_companyและมุมมองที่เรียกว่าLIVING_CUSTOMERS_VWกำหนดเช่น:

เลือก first_name, last_name
จาก CONTACT.NAMES
WHERE (is_alive = 'จริง')

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


0

ฉันเห็นด้วยกับการใส่ชื่อตารางในชื่อฟิลด์ ID ด้วยเหตุผลที่คุณระบุ โดยทั่วไปนี่เป็นช่องเดียวที่ฉันจะใส่ชื่อตาราง


0

ฉันเกลียดชื่อรหัสธรรมดา ฉันขอแนะนำให้ใช้ invoice_id หรือตัวแปรของสิ่งนั้นเสมอ ฉันมักจะรู้ว่าตารางใดเป็นตารางที่เชื่อถือได้สำหรับ id เมื่อฉันต้องการ แต่สิ่งนี้ทำให้ฉันสับสน

SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.InvoiceID = inv.ID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.ID = inv.InvoiceLineID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.ID = inv.InvoiceID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.InvoiceLineID = inv.ID 

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


2
ฉันอ่านคำว่า "ใบแจ้งหนี้" หลายครั้งเกินไปในโพสต์นี้ ตอนนี้ดูตลกแล้ว
Kevin

2
ฮึโดยปริยาย! ฉันอยากจะฉีกดวงตาของฉันออกไปมองสิ่งนั้น
HLGEM

0

ฉันชอบ DomainName || 'ID' (เช่น DomainName + ID)

DomainName มักจะเป็นชื่อเดียวกับ TableName แต่ไม่เสมอไป

ปัญหาเกี่ยวกับ ID ทั้งหมดก็คือมันไม่ได้ขยายขนาดขึ้นไป เมื่อคุณมีตารางประมาณ 200 ตารางแต่ละคอลัมน์มีชื่อคอลัมน์แรกข้อมูลจะเริ่มมีลักษณะเหมือนกันทั้งหมด หากคุณมีคุณสมบัติ ID ที่มีชื่อตารางอยู่เสมอนั่นช่วยได้เล็กน้อย แต่ไม่มาก

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

ในบางครั้งชื่อโดเมน || ไม่สามารถใช้ "ID" ได้เนื่องจากจะมีสองคอลัมน์ในตารางเดียวกันที่มีชื่อเดียวกัน ตัวอย่าง: พนักงาน EmployeeID และพนักงาน SupervisorID ในกรณีดังกล่าวฉันใช้ RoleName || 'ID' ดังตัวอย่าง

สุดท้าย แต่ไม่ท้ายสุดฉันใช้คีย์ธรรมชาติมากกว่าคีย์สังเคราะห์เมื่อเป็นไปได้ มีสถานการณ์ที่กุญแจธรรมชาติไม่สามารถใช้งานได้หรือไม่น่าไว้วางใจ แต่มีหลายสถานการณ์ที่กุญแจธรรมชาติเป็นทางเลือกที่เหมาะสม ในกรณีเหล่านั้นฉันปล่อยให้คีย์ธรรมชาติรับชื่อตามธรรมชาติ ชื่อนี้มักไม่มีตัวอักษร 'ID' อยู่ด้วยซ้ำ ตัวอย่าง: OrderNo โดยที่ No เป็นตัวย่อของ "Number"


0

สำหรับแต่ละโต๊ะฉันเลือกชวเลขอักษรต้นไม้ (เช่นพนักงาน => Emp)

ด้วยวิธีนี้คีย์หลักที่เป็นตัวเลขอัตโนมัติจะกลายเป็นnkEmp nkEmp

มันสั้นไม่ซ้ำกันในฐานข้อมูลทั้งหมดและฉันรู้คุณสมบัติของมันได้อย่างรวดเร็ว

ฉันใช้ชื่อเดียวกันใน SQL และทุกภาษาที่ฉันใช้ (ส่วนใหญ่เป็น C #, Javascript, VB6)


0

ดูรูปแบบการตั้งชื่อของไซต์ Interakt สำหรับระบบการตั้งชื่อตารางและคอลัมน์ที่ผ่านการพิจารณาอย่างดี วิธีนี้ใช้คำต่อท้ายสำหรับแต่ละตาราง ( _prdสำหรับตารางผลิตภัณฑ์หรือ_ctgสำหรับตารางประเภท) และต่อท้ายคอลัมน์นั้นในแต่ละคอลัมน์ในตารางที่กำหนด ดังนั้นคอลัมน์ข้อมูลประจำตัวสำหรับตารางผลิตภัณฑ์จะเป็นid_prdและไม่ซ้ำกันในฐานข้อมูล

พวกเขาก้าวไปอีกขั้นเพื่อช่วยในการทำความเข้าใจคีย์ต่างประเทศ: คีย์ต่างประเทศในตารางผลิตภัณฑ์ที่อ้างอิงถึงตารางหมวดหมู่จะเป็นidctg_prdที่ชัดเจนว่าเป็นตารางใด_prdคำต่อท้าย) และหมายถึงตารางใด (หมวดหมู่) .

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


-2

คุณสามารถใช้หลักการตั้งชื่อต่อไปนี้ มันมีข้อบกพร่อง แต่ช่วยแก้ปัญหาเฉพาะของคุณได้

  1. ใช้ชื่อเล่นสั้น ๆ (3-4 ตัวอักษร) สำหรับชื่อตารางเช่น Invoice - inv, InvoiceLines -invl
  2. ชื่อคอลัมน์ในตารางโดยใช้ชื่อเล่นเหล่านั้นเช่นinv_id,invl_id
  3. สำหรับคอลัมน์อ้างอิงใช้invl_inv_idสำหรับชื่อ

วิธีนี้คุณสามารถพูดได้

SELECT * FROM Invoice LEFT JOIN InvoiceLines ON inv_id = invl_inv_id

5
อิ๊ก! ฉันจะโหวตไม่ให้ใช้ชื่อเล่นสั้น ๆ สำหรับตาราง (หรือวัตถุอื่น ๆ ) ด้วยชื่อเล่นคุณจะไม่มีทางรู้แน่ชัดว่าชื่อย่อคืออะไร จำไว้ว่ามีหลายวิธีในการสะกดผิด มีทางเดียวเท่านั้นที่จะสะกดให้ถูกต้อง
James Curran

1
เจมส์ฉันไม่เห็นด้วย หากคุณมีชื่อสั้น ๆ ที่ไม่สื่อความหมายและจำไม่ได้ว่าชื่ออะไรแสดงว่าคุณเลือกชื่อผิดหรือไม่เข้าใจหลักการตั้งชื่อที่คนอื่นเลือก
kemiller2002

2
ใช้นามแฝงเพื่อให้ได้เอฟเฟกต์เดียวกัน เลือก * จากใบแจ้งหนี้ใบแจ้งหนี้ซ้ายเข้าร่วม InvoiceLines invl บน inv.ID = invl.InvoiceID
yfeldblum

2
ไม่ไม่ไม่ไม่. นามแฝงตารางที่มีความล้มเหลวในแบบสอบถาม แต่ชื่อตารางควรเป็นแบบเต็ม
ตาข่าย

2
เหตุใดโปรแกรมเมอร์จำนวนมากจึงขี้เกียจและดูเหมือนว่าคำตอบของทุกสิ่งคือการพิมพ์น้อยที่สุดเท่าที่จะทำได้เพียงเพราะมันยากเกินไปที่จะพิมพ์เพิ่มอีกเล็กน้อย
mP.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.