Birincil anahtar / yabancı Anahtar adlandırma kuralı [kapalı]


98

Geliştirme grubumuzda, Birincil ve Yabancı Anahtarlar için adlandırma kuralıyla ilgili şiddetli bir tartışmamız var. Grubumuzda temelde iki düşünce okulu var:

1:

Primary Table (Employee)   
Primary Key is called ID

Foreign table (Event)  
Foreign key is called EmployeeID

veya

2:

Primary Table (Employee)  
Primary Key is called EmployeeID

Foreign table (Event)  
Foreign key is called EmployeeID

Tablonun adını sütunların hiçbirinde çoğaltmamayı tercih ederim (Bu nedenle yukarıdaki 1. seçeneği tercih ederim). Kavramsal olarak, özellik adlarında nesnenin adını kullanmadığınız diğer dillerde önerilen uygulamaların çoğu ile tutarlıdır. Yabancı anahtarı adlandırmanın EmployeeID(veya Employee_IDdaha iyi olabileceğini) okuyucuya bunun IDTablonun sütunu olduğunu söylediğini düşünüyorum Employee.

Bazıları seçenek 2'yi tercih eder, burada birincil anahtarı tablo adı ile ön ek olarak adlandırırsınız, böylece sütun adı veritabanı genelinde aynı olur. Bu noktayı görüyorum, ancak artık birincil anahtarı görsel olarak yabancı anahtardan ayıramazsınız.

Ayrıca, tablo adının sütun adında bulunmasının gereksiz olduğunu düşünüyorum, çünkü tabloyu bir varlık ve bir sütunu o varlığın bir özelliği veya özniteliği olarak düşünürseniz, onu Employeedeğil EmployeeIDbir çalışanın niteliği. Bir onun ya benim astı sormuyorsun PersonAgeveya PersonGenderolduğunu. Ona Yaşının kaç olduğunu soruyorum.

Dediğim gibi, bu şiddetli bir tartışma ve biz bu konuda sürekli devam ediyoruz. Yeni bakış açıları edinmekle ilgileniyorum.



1
10'dan fazla benzer soru okudum ve sonunda en iyi 3 cevabın iyi olduğunu buldum: stackoverflow.com/a/465146/781695
kullanıcı

Sadece bir ek not: 2. Seçenek 'Doğal Katılma' yapmanıza izin verecektir. Heck, neden hala 'Employee.ID'yi EmployeeID olarak ekleyerek 1. seçimde yapmıyorsunuz? Ancak daha iyi uygulama yolu, 'ON Employee.ID = Event.EmployeeID' kullanarak 'Katıl' gibi görünüyor.
Leo

Her iki durumda da, bir veya daha fazla kuyrukta takma ad (veya 'tablo_adı.sütun_adı') kullanmak zorunda kalacaksınız çünkü her iki durumda da sütun adlarını tekrarlıyorsunuz.
Please_Dont_Bully_Me_SO_Lords

Yanıtlar:


54

Gerçekten önemli değil. 1. seçim ile 2. seçenek arasında gerçek bir farkın olduğu bir sistemle asla karşılaşmadım.

Jeff Atwood'un bir süre önce bu konuda harika bir makalesi vardı. Temelde insanlar yanlış olduğu kanıtlanamayacak konuları en öfkeyle tartışır ve tartışırlar. Ya da farklı bir açıdan, yalnızca haydut tarzı dayanıklılığa dayalı son adam-ayakta duran argümanlarla kazanılabilecek konular.

Birini seçin ve kodunuzu gerçekten etkileyen konulara odaklanmalarını söyleyin.

DÜZENLEME: Eğlenmek istiyorsanız, yöntemlerinin yinelemeli tablo referansları için neden üstün olduğunu uzun uzun belirtmelerini sağlayın.


28
+1, sağduyu için ...
Tartışılacak

5
Ve kendi kendine referans veren DRI için, aynı PK'ye kendi kendine referans veren birden fazla FK olduğunda, her iki "standardı" da ihlal etmeniz GEREKİR çünkü iki FK sütunu aynı şekilde adlandırılamaz ... örneğin EmployeeTable EmployeeId PK, SupervisorId FK, MentorId Fk, PartnerId FK, vb. ile ...
Charles Bretana

77

İki sütun her iki tabloda da aynı ada sahipse (kural # 2), SQL'de KULLANMA sözdizimini bir miktar yazma ve bazı standart gürültüyü kaydetmek için kullanabilirsiniz:

SELECT name, address, amount
  FROM employees JOIN payroll USING (employee_id)

2 numaralı sözleşmenin lehine olan bir başka argüman da ilişkisel modelin tasarlanma şeklidir .

Her sütunun önemi, kısmen karşılık gelen alanın adıyla etiketlenerek aktarılır.


4
SQL sözdizimi ve anlambilim aslında nasıl kullanılması gerektiğine dair oldukça iyi bir ipucu veriyor. Örneğin, sözdiziminin kullanılması, aynı etki alanına sahip sütunların aynı ada sahip olması gerektiği anlamına gelir, NULL = NULL -> NULL, NULL'un "uygulanamaz" yerine "bilinmeyen" olduğu anlamına gelir ve ON UPDATE CASCADE, anahtarların değişmez değil, yalnızca benzersiz olması gerektiği anlamına gelir.
Steven Huwig

7
Daha da iyisi, bu izin verir: SELECT name, address, amount FROM employees NATURAL JOIN payroll.
11.45'te bir gün

6
Dağıtılmış kodda doğal birleştirme kullanmam çünkü şema eklemelerinde daha da kısırdır. Ancak etkileşimli sorgulama için harika.
Steven Huwig

3
+1 ama her zaman bir istisna vardır. Örneğin, maaş bordrosunda, her ikisi de çalışanın yabancı anahtarı olan iki sütununuz varsa (örneğin, ödenen kişiye, ikincisi bütçe yetkisine sahip yöneticiye referans). Ancak her iki yabancı anahtarı da adlandıramayız employee_id.
Bill Karwin

1
"Using" anahtar sözcüğü MySql'e özgüdür. T-SQL'de çalışmıyor - ne yazık ki.
birdus

12

Bence başvurunuzun nasıl bir araya getirildiğine bağlı. ORM kullanıyorsanız veya tablolarınızı nesneleri temsil edecek şekilde tasarlarsanız, seçenek 1 sizin için olabilir.

Veritabanını kendi katmanı olarak kodlamayı seviyorum. Her şeyi ben kontrol ediyorum ve uygulama sadece saklı prosedürleri çağırıyor. Özellikle çok sayıda tablo birleştirildiğinde ve birçok sütun döndürüldüğünde, tam sütun adlarına sahip sonuç kümelerine sahip olmak güzeldir. Bu uygulama türü ile seçenek 2'yi seviyorum. Sütun adlarının birleşimlerde eşleşmesini gerçekten seviyorum. Eşleşmedikleri eski sistemler üzerinde çalıştım ve bu bir kabustu.


4
Eşleşmeyen sütun adlarına sahip birleşimleri bulmak zorunda kalmak için +1
Raj Daha

4
"eski sistemler" de 8 karakter uzunluğundaki isimlerden çok daha fazla acı veren handikap. Bir uzvun dışına çıkıp, ID adlı PK'ye sahip olmanın, uğraştığınız eski sistemlerdeki kabusun ana nedeni olmadığını tahmin etmeye hazırım. Ayrıca "eski sistemlerde emildi", yazılım geliştirmede, özellikle veri tabanlarında çok sık kullanılmaktadır. İnsanların, 10+ yıl önce piyasaya sürülen bir DB sistemindeki deneyimlerine dayanarak, herhangi bir A uygulamasını meşrulaştırdığını rutin olarak görüyorum.
Russell Steen

2
bugünün son teknoloji uygulamaları birkaç yıl içinde eski saçmalık olacak . Hatta arayüzü yeniden yazabilir veya verileri başka bir platformda kullanabilirsiniz, ancak verilerinizin (sütun adlarınız dahil) zaman testine dayanması gerekir.
KM.

2
Öyleyse 20 yıl önce insanlar, sadece 8 karaktere sahip olmalarına rağmen bugün mantıklı olan sütun adlarını kullanmalıydı? Veri depolama formatları son 20 yılda önemli ölçüde değişti ve önümüzdeki 20 yılda tekrar değişecek. Tercihinizin, zaman testine listelenen diğer yöntemlerden daha iyi dayanacağını göstermenin hiçbir yolu yok. Verileri saklama ve kullanma becerimiz geliştikçe, insanlar 20 yıldır bu tartışmayı yaparken "sütun adları" kendileri "eski saçmalık" olabilir. Tablolar, veri ilişkilerini kusurlu bir şekilde temsil eden bir insan yapısıdır ...
Russell Steen

1
İyi gerekçeli entelektüel yanıt için teşekkür ederim.
Russell Steen

4

Aşağıdakileri düşündünüz mü?

Primary Table (Employee)   
Primary Key is PK_Employee

Foreign table (Event)  
Foreign key is called FK_Employee

3
İnsanların oy vermesine dayanamıyorum ve nedenini belirtmiyorum. Bu tamamen geçerli bir cevap, bazıları için lezzetli olsun ya da olmasın farklı bir sorudur, ancak bu özneldir ve olumsuz bir oylamayı gerektirmez.
Jeremy

1
Bunu işaret ettiğiniz için teşekkürler. Ben de neden nedenlerden ilgi olacağını değil bu biçimi kullanın. Ve bunun iyi nedenleri olacağından oldukça eminim ...
Wouter

table_name.column_nameSorgularda kullanmak zorunda kalmayacağınız ve tekrarlanan adlar yoksa sütun adları için takma ad kullanmak zorunda kalmayacağınız için en iyi çıkış yolu budur ...
Please_Dont_Bully_Me_SO_Lords

1
Bu, bir Macar gösterim şekli olarak düşünülebilir. Öyleyse bunun lehine ve aleyhine olan argümanları düşünün.
Fred

3

Her iki konvansiyon da her durumda işe yaramıyor, öyleyse neden bir tane var? Sağduyu kullanın...

Örneğin, kendine referans veren tablo için, aynı tablonun PK'sine kendi kendine referans veren birden fazla FK sütunu olduğunda, her iki "standardı" da ihlal etmeniz GEREKİR çünkü iki FK sütunu aynı şekilde adlandırılamaz ... örn. , EmployeeId PK ile EmployeeTable, SupervisorId FK, MentorId Fk, PartnerId FK, ...


1
Gerçek teknik objektif cevap için +1
DVK

İyi, uygulanabilir bir cevap, ancak Dems'in cevabına yönelik argümanlar asıl noktayı kaçırıyor.
JYelton

3

Aralarında seçim yapılacak çok az şey olduğuna katılıyorum. Bana göre her iki standartla ilgili çok daha önemli bir şey "standart" kısımdır.

İnsanlar 'kendi işlerini yapmaya' başlarlarsa, komşuları tarafından asılmalıdırlar. BENİM NACİZANE FİKRİME GÖRE :)


3
Tutarlılığın "doğru" olmaktan daha önemli olduğunu kabul etmek için +1 (bu durumda)
Russell Steen

"Aptalca bir tutarlılık" uygulamaya çalışmak için -1. Eski Çin atasözü "Aptalca bir tutarlılık, basit beyinler için bir hobgoblindir" der.
Charles Bretana

@charles: Farklı insanların birbirlerinin kodlarını korudukları bir dünyada, genellikle yazar ayrıldığında ve dokümantasyon eskimiş veya mevcut değilse, bu aptalca bir tutarlılık değildir. Seninle çalışmadığıma çok sevindim ...
MatBailie

@Dems, alınacak bir şey yok, ama bu iki nedenden dolayı aptalca. 1) HERHANGİ BİR standardın ihlal edilmesi GEREKEN yaygın, açıkça anlaşılmış senaryolar vardır. (Örnekler için cevabıma bakın ve 2) çünkü en azından bu konuda bir standart, standartları seven insanları daha rahat hissettirmek dışında çok az değer
katacaktır

1
"ID" nin daha tutarlı olduğunu iddia edebilirsiniz - çünkü "arabalar" tablosunda veya "araba" tablosunda İngilizce "carID" yi tanıttığınız anda? "Koyun" sofrasında veya "koyunlarda" "koyun kimliği" - işler tutarsızlaşmaya başlar. "ID" ve tekil tablo adlarına sadık kalırsanız - bu sadece tutarlı değildir, birçok ORM ile iyi oynar / daha az yapılandırma gerektirir (örn. Dapper Contrib)
niico

2

Çalıştığım yerde kullandığımız kural, tabloları çoğul biçimde adlandırmamız (yani, "çalışanlar") ve tablo ile sütun adı arasında alt çizgi kullanmamız dışında, A'ya oldukça yakındır. Bunun yararı, bir sütuna nasıl erişmek istediğinize bağlı olarak "çalışanlar _ kimliği" veya "çalışanlar.kimliği" şeklinde olmasıdır. Sütunun hangi tablodan geldiğini belirtmeniz gerekirse, "çalışanlar.employees _ id" kesinlikle gereksizdir.


Çoğul tablo adlarını sevip sevmediğime karar vermedim. Tekil kullanarak sorgular daha iyi okunur gibi görünür ("çalışanlar.adı" yerine "çalışan.adı"). Birleştirmelerde bile, tek kayıtları başka bir tabloya katarken daha iyi okunuyor gibi görünüyor. Ancak çoğullaştırılmış tablo adları, sorgu yerine tablo hakkında düşünürken daha doğru görünüyor.
Kullandığımız

Evet. Daha çok kişisel bir tercih ve / veya her ne görmeye alışkınsanız, sanırım.
Jarett Millard

2

Yalnızca veritabanı sorgularına değil, uygulama koduna da bakıyorsanız, bazı şeyler bana açık görünüyor:

  1. Tablo tanımları genellikle doğrudan bir nesneyi tanımlayan bir sınıfa eşlenir, bu nedenle tekil olmaları gerekir. Bir nesnenin koleksiyonunu tanımlamak için genellikle tekil isme "Dizi" veya "Liste" veya "Koleksiyon" eklerim, çünkü çoğulların kullanımından daha açık bir şekilde bunun yalnızca bir koleksiyon olduğunu değil, aynı zamanda ne tür bir koleksiyon olduğunu da gösterir bu. Bu görünümde, koleksiyonun adı olarak değil, koleksiyon olduğu nesnenin türünün adı olarak bir tablo adı görüyorum. Uygulama kodunu yazmayan bir DBA bu noktayı kaçırabilir.

  2. Ele aldığım veriler genellikle anahtar olmayan tanımlama amaçları için "Kimlik" kullanır. Anahtar "ID" ler ile anahtar olmayan "ID" ler arasındaki karışıklığı ortadan kaldırmak için, birincil anahtar adı için, tablo adı veya kısaltması ile "Anahtar" (bu, değil mi? tablo adı. Bu ön ek (ve bunu yalnızca birincil anahtar için saklıyorum) anahtar adını benzersiz kılar, bu özellikle önemlidir çünkü veritabanı sütun adlarıyla aynı değişken adları kullanıyoruz ve çoğu sınıfın adıyla tanımlanan bir ebeveyni var ana anahtar. Bu aynı zamanda, tek başına "Anahtar" olan ayrılmış bir anahtar kelime olmadığından emin olmak için de gereklidir. Anahtar değişken isimlerinin tutarlı tutulmasını kolaylaştırmak ve doğal birleşimler sağlayan programlar sağlamak, yabancı anahtarlar, birincil anahtar oldukları tabloda kullanılanlarla aynı ada sahiptir. Doğal birleştirmeler kullanarak bu şekilde daha iyi çalışan programlarla birden fazla karşılaştım. Bu son noktada, kullandığım kendine referans veren tablolarla ilgili bir sorun olduğunu kabul ediyorum. Bu durumda, yabancı anahtar adlandırma kuralına bir istisna yapardım. Örneğin, o tablodaki başka bir kaydı işaret etmek için Çalışan tablosunda bir yabancı anahtar olarak ManagerKey'i kullanırdım.


Entity Framework gibi birçok nesne ilişkisel eşleyici (ORM), bir tabloyu farklı bir ada sahip bir sınıfa eşlemenize olanak tanır. Bu, "Kullanıcı" adlı bir sınıfa ve "Kullanıcılar" adlı bir tabloya sahip olmanızı sağlar.
Fred

2

Kural 2'yi seviyorum - bu konuyu araştırırken ve kendi soruyu göndermeden önce bu soruyu bulurken, şu sorunla karşılaştım:

Çok sayıda sütunu olan bir tablodan * seçiyorum ve onu benzer şekilde çok sayıda sütunu olan ikinci bir tabloyla birleştiriyorum. Her iki tabloda da birincil anahtar olarak bir "id" sütunu vardır ve bu, sonuçta bu iki değeri benzersiz kılmak için her sütunu (bildiğim kadarıyla) özel olarak seçmem gerektiği anlamına gelir, yani:

SELECT table1.id AS parent_id, table2.id AS child_id

Kural 2'yi kullanmak, sonuçta hala aynı ada sahip bazı sütunlara sahip olacağım anlamına gelse de, artık ihtiyacım olan kimliği (ebeveyn veya çocuk) belirleyebilirim ve Steven Huwig'in önerdiği gibi, USINGifade işleri daha da basitleştirir.


2
SELECT *zaten (çoğu) üretim sorgusu için hayır-hayırdır, bu nedenle bu bir adlandırma standardı seçmek için pek bir neden değildir.
P Daddy

1
Kabul etmiyorum: Bunun neden böyle olduğuna dair bir bağlantı verebilir misiniz? Sorgumda 80 sütunun adını korumak zorunda olma fikrinden hoşlanmıyorum.
JYelton

Şu anda bir bağlantı bulamıyorum ("*" için google zor), ancak temel noktaları özetleyeceğim: (1) tablolarda yapılan değişiklikler uygulamanızı olumsuz etkileyebilir, (2) olabilir performans açısından kötüdür ve (3) gerçekte hangi verilere ihtiyacınız olduğunu açıkça belirtmek kodunuzun anlaşılmasını kolaylaştırabilir. Bu noktalar genişleyebilir ve istisnalar da vardır (bahsettiğim gibi) ama bu burada uygun değil. Bunu yeni bir soru olarak gönderirseniz, ben (ve diğerleri) daha fazla ayrıntıya girmekten memnuniyet duyarız.
P Daddy

2
Ben yapabilirim. Performans avantajının farkındayım, ancak kodu düzenlerken zaman yatırımını dikkate almalıyım. Her zaman uygulama ile veritabanı arasındaki etkileşimi iyileştirmenin yollarını arıyorum. Teşekkürler.
JYelton

1
SELECT *Çoğu üretim sorgusu için hayır-hayır olduğundan o kadar emin değilim . Geliştirme hızınızı önemli ölçüde artırırsa ve kodunuzu çok daha kısa ve okunaklı hale getirirse - daha önemli konulara odaklanmanıza olanak tanır - neden olmasın SELECT *? Büyük ölçüde her durumun koşullarına bağlıdır ve birçok faktör arasında bir değiş tokuşdur. Bir kural nadiren her şeye uyar.
niico

2

Hep kullandım userId bir masa ve üzerinde bir olarak PK KullanıcıNo bir FK gibi başka masada. Birini diğerinden tanımlamak için userIdPK ve userIdFK'yi adlar olarak kullanmayı ciddi ciddi düşünüyorum . Tablolara bakarken PK ve FK'yi hızlı bir şekilde tanımlamama yardımcı olacak ve verilere erişmek için PHP / SQL kullanırken kodu temizleyerek anlaşılmasını kolaylaştıracak gibi görünüyor. Özellikle başkası koduma baktığında.


1

2 numaralı kuralı kullanıyorum. Şu anda, belirli bir tabloda ne anlama geldiğini bilmediğim eski bir veri modeliyle çalışıyorum. Ayrıntılı olmanın ne zararı var?


1

Yabancı anahtarı adlandırmaya ne dersiniz?

role_id

burada rol, başvurulan varlığın eldeki tabloyla göreli olduğu roldür. Bu, yinelemeli başvuru ve aynı tabloya birden çok fks sorununu çözer.

Çoğu durumda başvurulan tablo adıyla aynı olacaktır. Bu durumda, tekliflerinizden biri ile aynı hale gelir.

Her halükarda uzun tartışmalara sahip olmak kötü bir fikirdir


0

Order.employee_id = Employee.id ÜZERİNE çalışan INNER JOIN siparişinin "nerede" ek niteliklere ihtiyaç var mı? ".

Ek yeterliliğe gerek yok çünkü bahsettiğim yeterlilik zaten orada.

"Bir iş kullanıcısının Sipariş Kimliği veya Çalışan Kimliğine başvurmasının nedeni, bağlam sağlamaktır, ancak bir dabase düzeyinde zaten tabloya baktığınız için bağlamınız vardır".

Dua et, söyle bana, eğer sütunun adı 'ID' ise, o zaman bu "masaya hakemlik" tam olarak nasıl yapılır, bu referansı ID sütununa tam olarak bahsettiğim şekilde nitelemedikçe?

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.