Neden bir tablonun Birincil Anahtar sütununu “Id” olarak adlandırmak kötü bir uygulama olarak kabul edilir? [kapalı]


210

T-sql öğretmenim, PK sütunu "İD" olarak adlandırmanın başka bir açıklama yapmadan kötü bir uygulama olarak değerlendirildiğini söyledi.

Neden bir tabloyu PK sütununa "Id" adlandırmak kötü bir uygulama olarak kabul edilir?


27
Aslında bu bir açıklama değildir ve Id, çok açıklayıcı olan "kimlik" anlamına gelir. Bu benim düşüncem.
Jean-Philippe Leclerc

49
Id'yi PK adı olarak kullanan pek çok dükkan olduğuna eminim. TableId'i adlandırma kuralı olarak kullanıyorum, ancak kimseye BİR DOĞRU YOLU söyleyemem. Öğretmenin sadece fikrini geniş çapta kabul görmüş en iyi uygulama olarak sunmaya çalışıyor gibi görünüyor.

22
Kesinlikle o kadar da kötü olmayan kötü uygulama tipi. Önemli olan tutarlı olmaktır. Kimlik kullanıyorsanız, her yerde kullanın veya kullanmayın.
deadalnix

57
Bir tablonuz var ... buna Kişiler deniyor, bunun bir kimliği var, İd. Adında, kimliğin ne olduğunu düşünüyorsunuz? Araba? Bir tekne? ... hayır, bu insanlar kimliği, işte bu. Bunun kötü bir uygulama olmadığını ve PK sütununa Id dışında bir isim vermenin gerekli olmadığını düşünüyorum.
jim

38
Yani öğretmen sınıfın önüne geçip, bunun tek bir sebep olmadan kötü bir uygulama olduğunu söyler mi? Bu bir öğretmen için daha kötü bir uygulama.
JeffO

Yanıtlar:


247

Dışarı çıkıp söyleyeceğim: Gerçekten kötü bir uygulama değil (ve öyle olsa bile, o kadar da kötü değil ).

( Çad'ın işaret ettiği gibi) aşağıdaki sorgudaki gibi hataları gizleyebileceğini iddia edebilirsiniz:

SELECT * 
    FROM cars car
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

ancak bu, tablo adlarınız için küçük takma adlar kullanmamak suretiyle kolayca azaltılabilir:

SELECT * 
    FROM cars
    JOIN manufacturer
        ON manufacturer.Id = cars.ManufacturerId
    JOIN models
        ON models.Id = cars.ModelId
    JOIN colors
        ON manufacturer.Id = cars.ColorId

HER ZAMAN 3 harfli kısaltmalar kullanan uygulamalar benim için sütun adını kullanmaktan daha kötü görünüyor id. (Konuya ilişkin örnek: tablo isminin carskısaltması ile aslında kim kısaltılır car? Bu ne işe yarar?)

Mesele şu: tutarlı olmak. Şirketiniz Id kullanıyorsa ve genellikle yukarıdaki hatayı yaparsanız, tam tablo adlarını kullanma alışkanlığı edinin. Şirketiniz Kimlik sütununu yasaklarsa, onu adım adım atın ve tercih ettikleri adlandırma kurallarını kullanın.

Bu gibi sorunları çözmek yerine GERÇEKTEN kötü uygulamalar (çoklu iç içe geçmiş alt sorgular gibi) olan şeyleri öğrenmeye odaklanın. "ID" sütunlarınızı isimlendirme konusu kötü bir uygulama olmaktan ziyade bir zevk meselesi olmaktan daha yakındır.


EDİTÖRLER İÇİN BİR NOT: Bu sorgudaki hata kasıtlı ve bir noktaya işaret etmek için kullanılıyor. Lütfen düzenlemeden önce tam cevabı okuyunuz.


1
@Chad, bu belirli sorguda anlamlı görünmese bile, tablo adlarına takma adlar için 3 harf kullandığınız gerçeğinin bir referansıydı ( cars-> car. Tanrıya şükür - parmaklarımı kurtardınız). Çok derinden okuma.
riwalk

3
takma isimlerimden daha kötüsü, çoğulculuk karışımım carsve manufacturer. Biri çoğul, diğeri değil. İnsanlar db'de seçim yapmak istiyorsa, seçilmesi gereken kötü uygulama budur.
CaffGeek

3
Bence bu kötü bir uygulama. Açıkçası, kötü uygulamalara gidince korkunç değil .. ama kaçınması çok kolay, neden olmasın? Şimdi, bir giriş dersi için odaklanılması gereken şeyin bu olduğuna katılıyorum? Muhtemelen hayır ....
user606723

2
@ user606723, aslında, bir giriş dersi için bunun bir şey ifade etmesi gereken önemli bir şey olduğunu düşünüyorum. En iyi uygulamaları öğretmek temel olmalıdır. Sonuçları ve tradeoffasyonları anladığınıza ve en iyi uygulamalardan ne zaman sapmanız gerektiğine dair deneyimlinceye kadar değil.
CaffGeek

5
@Chad, katılmıyorum kabul ediyorum. Öğrencilere "en iyi uygulamaları" öğretmelerine, neden bunların en iyi uygulamaların olduğunu anlamalarına izin vermek boşuna bir çabadır. Ve her şeyi kapsayamayacağınız için, bu noktaya “sadece yapmamalısınız, neden sonra anlayacaksınız” diyerek bir profesörün bakış açısından oldukça akıllıca bir seçimdir. Meraklı öğrenciler buraya yazabilir veya umarım bu soruyu daha önce cevaplanmış olarak bulabilir. (Veya
dersten

123

Çünkü yabancı anahtar içeren bir tablonuz olduğunda, bu yabancı anahtarın "Id" adını veremezsiniz. Tablonun adı TableId.

Ve sonra katılımın benziyor

SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId

Ve ideal olarak, durumunuz her iki tarafta aynı alan adına sahip olmalıdır.

SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId

Bu yüzden Id'i Üretici Kimliği olarak adlandırmak gereksiz görünmekle birlikte, hataların ortaya çıkması nedeniyle katılım koşullarınızda hatalarınız olması daha az olasıdır.

Bu basit görünüyor, ancak birkaç masaya katıldığınızda, hata yapma olasılığınız artar, aşağıdakileri bulun ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

Uygun adlandırmada, hata ortaya çıkıyor ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.ManufacturerId = car.ManufacturerId
    JOIN models mod
        ON mod.ModelId = car.ModelId
    JOIN colors col
        ON mfg.ManufacturerId = car.ColorId

Onları Id olarak adlandırmanın başka bir nedeni "kötü" dür ki, birkaç tablodan bilgi ararken, onları ayırt edebilmeniz için Id sütunlarını yeniden adlandırmanız gerekir.

SELECT   manufacturer.Id as 'ManufacturerId'
        ,cars.Id as 'CarId'
        --etc
    FROM cars 
    JOIN manufacturer
        ON manufacturer.Id = cars.Id

Doğru isimlerle bu daha az sorun olur


174
Bunun benim için yeterince iyi bir açıklama olduğundan emin değilim. Söylemekte yanlış olan bir şey yok SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId. idYıllardır kullandım ve gerçek bir sorun olarak tanımladığınız şeyi asla bulamadım.
riwalk

61
Buradaki kötü uygulamanın, mfg veya mod gibi bir isimdeki tabloları takmak olduğunu söyleyebilirim. suppliers.id = cars.manufacturer_id çok okunabilir ve hata da çözülecek.
deadalnix

5
@Chad> Ben zaten aptal değişken isimleri ile ilgili sorunlar var. Bir cok zaman. Rekor için, burada benim ekibimde bunu yapan bir geliştiriciye söyleyeceğim şey, "mfg üretici anlamına gelmez, bu, üreticiyi yazmak için tembel olacağınız anlamına gelir".
deadalnix

9
@ Stargazer712: SELECT * işlevini 2 tablodan yapmak 2 x ID sütunu verir. Kimlik şimdi belirsiz: sıra veya isimle başvuru yapıyor musunuz? SELECT * ya iyi bir uygulama değildir. Zavallı argümanlar. Kırılgan kodu. Çad
haklı

6
@gbn, yine, sadece yaparsanız, bütün belirsizlik ortadan kalkar SELECT manufacturer.id FROM .... Ortaya çıkan her zorluk idçok kolay bir şekilde üstesinden gelinebilir, bu da sadece bir zevk meselesidir.
riwalk

67

Ruby'nin ActiveRecord kütüphanesi ve Groovy'nin GORM'i varsayılan olarak vekil anahtar için "id" kullanır. Bu uygulamayı sevdim. Her sütun adındaki tablo adının çoğaltılması gereksizdir, yazmak sıkıcıdır ve okumak daha sıkıcı olacaktır.


30
"+1" ve okunması daha sıkıcı. " - adlandırma kuralları özensiz kod için bir yardım grubu olarak düşünülmemeli, öncelikli olarak okunabilirliği arttırmalıdır.
ocodo

12
Kimlik okumak için çok daha sıkıcı
HLGEM

5
@HLGEM: Sütun adını her zaman tablo adı ile niteleyebilirsiniz.
kevin cline '20:

2
Okumak daha sıkıcı dışında katılıyorum. Aslında daha açıklayıcı sütun adları okumayı ve o sütunun gerçekte ne olduğunu bulmak için daha az zaman harcamayı tercih ediyorum.
Devin Dixon

2
+1, Send.postID, Posts.postName gibi sütunlarla tabloları görmekten nefret ediyorum, burada sadece post.id ve post.name kullanmak çok daha güzel.
Doug,

40

"Ad" veya "Id" gibi genel veya anahtar sütun adlarına, TableName ile önceden eklenmesi gerekir.

Her iki "Id" değerine ihtiyaç duyulduğunda belirsizliği ortadan kaldırır, aranması daha kolay, çok daha az sütun diğer adı anlamına gelir.

Daha az kullanılan veya denetim sütunu veya anahtar olmayan (LastUpdatedDateTime demek) önemli değil


57
Bunu yaparsan, fazladan yazmamı sağladığın için senden nefret ediyorum !!!! Masanın adı Person, kimliğin ne olacağını düşünüyorsun? Araba? hayır, bu kişi.
jim

16
@jim, seni tanımıyorum, ama 6 tane daha fazla karakter yazmak beni yaklaşık yarım saniye sürüyor. Ve nadiren tek bir tablodan birini seçtiğimi ve bu nedenle 'Id' adında iki sütunla sonuçlanacağını ve herhangi bir şekilde tablo / takma adını eklemeniz gerekeceğini düşündüğümde, yazılan karakter sayısında tasarruf yoktur.
CaffGeek

21
@Ben gereksiz buldum. Katılmam durumunda, c.id = m.manufacturerid, bende sorun yok. Bu sütunlar genellikle bir şekilde bir sınıfa "eşlenir" ve Person.PersonId ile bir sınıfa sahip olmak beni kusturmak istememe neden olur ... Evet, sorunlarımın tamamen farkındayım.
jim

20
Ben de buna katılmıyorum. Neden durdurmak nameve id? Neden her sütun için tablo adı belirtilmemiş? Bir önek eklemek için bu iki ismi seçmek keyfi görünüyor. Kavramsal olarak, yine de bir sütun içeriğine sahip olmak için tabloya sahip olmalısınız. Sorguyu netleştirmek için neden bu tablo adını kullanmıyorsunuz: Person.Name, Animal.Name, Part.Name, ...
Thomas

11
@Bill Leeper, DRY, veritabanı geliştirmede her zaman uygun değildir. Veritabanlarında, önemli olan performans ve veritabanının DRY ilkelerini yerine getirmek için fazladan çalışma yapmasıdır (örneğin skaler işlevler veya çok fazla sütun döndüren görünümler veya sorgular çağıran görünümler kullanmak veya varolan bir işlemi kullanmak için 1000000 kayıt eklemek için bir imleç kullanmak gibi) genellikle kontrendikedir. Nesne yönelimli dünyada, bir şeylerin veritabanı tasarımında uygun olduğunu düşünmeyin. Düşüşünüz uygunsuzdu. ID kullanımı bilinen bir SQL antipattern'dir.
HLGEM

31

Bu iplik öldü ama IMO o eklemek istiyorum değil kullanarak Idkötü bir uygulamadır. IdKolon özel olduğu; öyle birincil anahtar. Herhangi bir tablonun herhangi bir sayıda yabancı anahtarı olabilir, ancak birincil olan yalnızca bir anahtarı olabilir. Tüm birincil anahtarların çağrıldığı bir veritabanında , tabloya bakar bakmaz hangi sütunun birincil anahtar olduğunu tam olarak bilirsiniz.Id

İnan bana, aylardır bütün gün her gün çok sayıda büyük veritabanında (Salesforce) çalışarak geçirdim ve şemalar hakkında söyleyebileceğim en iyi şey, her tablonun adı verilen birincil bir anahtar olduğu Id. Sizi temin ederim ki, bir PKK'ya yabancı bir anahtara katılmak konusunda hiçbir zaman kafam karıştı Id. İnsanların bahsetmediği diğer bir şey ise, masaların uzun saçma isimleri Table_ThatDoesGood_stuff__c; Bu isim yeterince kötü, çünkü mimar o masayı düşündüğü sabah bir akşamdan kalmaydı, ama şimdi bana ana anahtarı çağırmamanın kötü bir uygulama olduğunu söylüyorsunuz Table_ThatDoesGood_stuff__cId (SQL sütun adlarının genel olarak büyük / küçük harf duyarlı olmadığını unutmayın).

Dürüst olmak gerekirse, bilgisayar programlamayı öğreten çoğu insanla ilgili problemler, yıllardır bir üretim kodu satırı yazmamış olmaları ve çalışan bir yazılım mühendisinin gerçekte ne yaptığı hakkında hiçbir fikirleri olmamasıdır. Çalışmaya başlayana kadar bekleyin ve sonra ne düşündüğünüzün iyi bir fikir olduğuna karar verin.


2
Bu, birincil anahtarlarınızdan hiçbiri birleşik bir anahtar değilse, bu durum ne yazık ki, çok sık sık olan bir durumdur. Bir kişi gerçekten sadece özel durumlarda anahtar kullanmalı.
nicodemus13

6
Id'yi kullanmak, düşüncesiz geliştiricilerin yaptıkları her tabloya birincil anahtar kimliği ekledikleri bir durumla sonuçlanır. İlişkisel veritabanlarının temellerinden biri, anlamlı ve toplam birincil anahtarların kullanılması ve kimliğin kullanılması yardımcı olmamaktır.
Pieter B

Bu cevap, sanırım tartışılan argümanlarla "Ben Id'yi tercih ediyorum" diyor gibisin. Argümanınız, Id adlı birini bularak hangi anahtarın birincil anahtar olduğunu anında görebilirsiniz. Eh, o tableId ile tam aynı değil . Hangi anahtarın ana anahtar olduğu da kafamı karıştırmaz. Sadece kimlikten önce tablo adını taşıyan birini arıyorum. Sadece bu değil, aynı zamanda ilk sütunun birincil anahtar olmadığı yerlerde ne tür bir ağzı açık masalarla çalışıyorsunuz? Bu cevabınızdaki tüm argümanlarınızın tamamen tercihli olduğunu ve "tableId bana kendimi yanlış hissettirdiğini" düşünüyorum.
Dallin

@dallin tüm cevaplar tartışılır, aksi halde birisi sadece resmi standarda bağlanır ve bir tane olmaz!
James

@James StackExchange sitelerinin hedefi, düşünülmüş cevapları azaltmaktır. Bu yüzden sorular çok fazla tartışılmaya başlandı. Kabul edildi, bence bu sorunun neden bu kadar kapalı olduğunu düşünüyorum - çünkü görüşlü cevaplar ortaya çıkarmaktadır, ancak bu özel cevabın gerçeklere dayanan herhangi bir gerçek destekleyici gerçek veya argüman olmadan aşırı derecede düşünülmüş olduğunu düşünüyorum. benim fikrim, kimliği kullanmalısın, çünkü sevdiğim şey buydu ". Bu değerli bir cevap değil.
dallin

24

Kötü bir uygulama olduğunu düşünmüyorum. Tutarlılık her zamanki gibi kraldır.

Bence her şey bağlamla ilgili. Tablo bağlamında kendi başına, "id" tam olarak ne beklediğinizi, başka türlü ile aynı (veya aynı şekilde) görünebilecek diğerlerine karşı benzersiz bir şekilde tanımlamaya yardımcı olacak bir etiket anlamına gelir.

Birleşme bağlamında, birleşme yerlerini sizin ve ekibinizin okunabilir hale getirecek şekilde inşa etmek sizin sorumluluğunuzdadır. Tıpkı ifadelerin zayıf ifadelerle veya adlandırmada zor görünmesine olanak sağladığı gibi, takma adların ve yorumların etkili kullanımıyla anlamlı bir sorgu oluşturmak da mümkündür.

Aynı şekilde, 'Foo' adında bir Java sınıfı, 'Foo' tarafından önceden eklenmiş özelliklere sahip değildir, tablo kimliklerini tablo isimleriyle ön eklemek zorunda değilsiniz. Genelde, bahsedilmekte olan kimliğin ne olduğu bağlamında açıktır .


5
İlişkisel veritabanı tabloları sınıf değildir .
Adam Robinson,

1
Ancak bunlar veri yapılarıdır ve PODO sınıflarına benzerler. Aynı adlandırma problemleri geçerlidir.
ocodo

4
@Slomojo: Hayır, basit nesnelere benzemiyorlar. Nesneye dayalı tasarım ve veritabanı tasarımı aynı değildir ve hatta ilişkili değildir. Bununla birlikte, bazı durumlarda benzer (hatta aynı) tasarımı verebiliyorlar, ki bunlar ilişkili olduklarını göstermiyor. Örneğin, m: m ilişkileri sınıflarda önemsizdir, ancak üçüncü bir ilişkilendirme tablosu olmayan iki tablo arasında olması imkansızdır.
Adam Robinson

1
Bunun bir isimlendirme stratejisiyle nasıl bir ilgisi olduğunu bilmiyorum. Analojim (açıkça?) Yalnızca bu kapsamda ele alınmaktadır.
ocodo

2
Üzgünüm, ima ettiğim anlam çok açık değildi, " bu anlamda sınıflara benziyorlar" demeliydim. Her iki durumda da, bu konuda aşırı bilgili olmak özellikle yapıcı olduğunu düşünmüyorum. Adlandırma açısından, tablolar ve sınıflar önemli miktarda benzerlikleri paylaşmaktadır. Bir çıkmazda gelişen en iyi uygulamalar revizyon için adil bir oyundur veya en azından tartışmaya açıktır. Bu soru-cevap içinde etkili bir şekilde örnekleyen çok şey var, ekleyecek başka bir notum yok.
ocodo

24

Gönderen data.stackexchange.com

Mesajlarda Id

BOOM, soru cevaplandı.
Şimdi öğretmenine SO'nun kötü veritabanı tasarımı uyguladığını söyle.


8
FK'lerde tahminim, isimlere dayanarak PostTypeId -> PostTypes.Id:; AcceptedAnswerId -> Answers.Id; OwnerUserId -> Users.Id. Neden bu kadar kolay bir uygulama 'kötü' olarak kabul edilmeli?
Sjoerd

3
Bu, en iyi uygulamalar hakkında herhangi bir şeyi tam olarak nasıl kanıtlar?
GBa

5
Bir şeyin yığınta kullanılıp kullanılmadığı iyi veya kötü bir uygulama olup olmadığını kanıtlamaz.
Pieter B

2
Yaptığı kanıt, bu uygulamanın bir uygulamanın ölçeklenebilirliğini ve kullanışlılığını hiçbir şekilde yasaklamamasıdır.
Cypher

1
Aslında SO pratik mükemmel değildir. Bu ismini kullanırdım: PostType -> PostType.Id; Kabul edildiYanıt -> Cevap.İd; OwnerUser -> User.Id
alpav

17

Masada doğal bir birleşme gerçekleştirmeyi zorlaştırır (ve kafa karıştırıcı) yapar, bu yüzden evet, eğer çok da kötü değilse kötüdür.

Natural Join, bunlardan birini görmüş olabileceğiniz eski bir SQL Lore eseridir (yani ilişkisel cebir): ⋈ belki de bir veritabanı kitabında. Demek istediğim Natrual Join, yeni bir fangled SQL fikri değil, DBMS'lerin onu sonsuza dek sürdüğü görülmesine rağmen, bu nedenle uygulamanız için yeni bir fangled fikri değil, görmezden gelmeniz bile mantıksız olabilir. bugünlerde onun varlığı.

Tüm ana anahtar kimliğinizi adlandırırsanız, doğal birleşimin kolaylığını ve sadeliğini kaybedersiniz. veya select * from dudes natural join carsyazılmış olması gerekecek . Eğer doğal bir birleşme yapabilirseniz, ilişkinin gerçekte ne olduğunu görmezden gelirsiniz, ki bence bu oldukça harika.select * from dudes inner join cars where cars.dudeid = dudes.idselect * from dudes inner join cars where dudes.carid = cars.id


Bir uygulama geliştiricisi olarak en son ne zaman tam olarak biçimlendirilmiş bir SQL seçicisi yazdığınızda saklı bir prosedür yazmıyorsanız? Modern dillerin tümü, bu ilişkiyi sizin için yöneten bir tür ORM özelliğini içerir. Sütun adı temiz manuel SQL yazabilmekten çok daha önemlidir.
Bill Leeper

4
@Bill Her zaman, birçok kez, günde birçok kez, geliştirdiğiniz dilden çok kod tabanınıza bağlı. Ve, teşhis için, eğer iyi ve derin ilişkiler kurmak istiyorsanız, bu doğal birleşimleri birbirine bağlayabilir ve tamamen saha kimliklerini aramaktan kaçınabilirsiniz. Ve St. Jerome'un dediği gibi, "SQL'in cehaleti veritabanlarının cehaletidir".
Peter Turner

Doğal birleşmelerin evrensel olarak desteklenmemesi dışında, IMO, doğal birleşimlerin okunması daha zordur. İlişkide iki sütun var mı yoksa sadece bir tane mi? Açık ve doğal birleşimlerden uzak durmak çok daha iyidir.
Thomas

1
@Tomas, ben de doğal birleştirme kodunu koymuyorum, ancak tanılama için, veritabanı gerçekten çalışacak şekilde modellendiğinde onları oldukça yararlı buldum.
Peter Turner

16

Her masaya "ID" yapıştırmanın en iyi fikir olmadığı bir durum vardır: USINGeğer destekleniyorsa , anahtar kelime. MySQL'de sıklıkla kullanıyoruz.

Örneğin, fooTablesütununda fooTableIdve barTableyabancı anahtarınız fooTableIdvarsa, sorgularınız aşağıdaki gibi oluşturulabilir:

SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)

Sadece yazmadan tasarruf etmekle kalmaz, alternatife kıyasla daha okunabilirdir:

SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)

Bu benim için en çok çıkan cevap. USINGAnahtar kelime postgres / mysql / sqlite veritabanı tarafından desteklenmektedir, kullanmak için bir gerekçe olarak diğer cevaplar listesinin bazı az yazar demektir idve nihayet benim sübjektif görüşüme göre daha okunabilir.
Michael Barton,

11

Neden sadece öğretmenine sormuyorsun?

Bunu düşünün, tüm tablolar PK sütunlarınız adlandırıldığında ID, yabancı anahtar olarak kullanılmasını kabus yapar.

Sütun adlarının anlamsal olarak önemli olması gerekir. IDgeneldir.


8
ne için çok genel? Bir masanın kimliği?
jim

3
Hangi masanın @Jim? idtek başına bir şey ifade etmiyor, özellikle başka bir tabloya giden yabancı anahtar bağlamında. Bunun hiçbir classesşeyle ilgisi yok ve temel temel ilişkisel veritabanı tasarımında yapılacak her şey var.

10
Hafifçe şişman olması için ait olduğu tablo. table.idbir idalana atıfta bulunmak için kabul edilebilir bir yoldur . Alan adının tablo adı ile ön eklenmesi gereksizdir.
ocodo

2
@ Slomoj, tablo adlarını canavar birleşimlerinde tek veya çift harfli kısaltmalar olarak adlandırırken, sütuna adı eklemekten daha açık değildir ve daha açıktır.

6
Hangi kabustan bahsediyorsun? Çalışanlarını, yöneticilerini temsil eden bir sütunu içeren, kendine referans veren bir yapınız olduğunu varsayalım. Yabancı anahtar ne denir? Çalışan olarak Muhtemelen PK'nız olarak adlandırılamaz. FK'nin ismi PK ile eşleşmek zorunda değildir. İçinde bulunduğu varlığı temsil ettiği şey için adlandırılmalıdır.
Thomas

7

Kimlik aşağıdaki nedenlerden dolayı kötüdür:

Çok sayıda raporlama sorgusu yaparsanız, ikisini de görmek istiyorsanız her zaman sütunları takma zorundasınız. Böylece başlamak için doğru şekilde adlandırabileceğiniz zaman kaybı olur. Bu karmaşık sorgular yeterince zordur (gereksiz yüzlerce iş yapmanın yükü olmadan, yüzlerce satır uzunluğunda sorgular yazarım).

Kod hatalarına neden olabilir. Doğal birleştirmenin kullanımına izin veren bir veritabanı kullanıyorsanız (bunu kullanmanız gerektiğini düşündüğümden değil, ancak özellikler kullanılabilir olduğunda birisinin kullanacağını sanmıyorum), onu kullanan bir geliştirici elde ederseniz yanlış şeye katılacaksınız.

Karmaşık bir sorgu oluşturmak için birleştirme kopyalıyorsanız, takma adı istediğinize değiştirmeyi ve yanlış bir birleşme elde etmeyi unutmak kolaydır. Her bir kimliği içinde bulunduğu tablodan sonra adlandırılmışsa, genellikle bir sözdizimi hatası alırsınız. Eğer pPK ismi ile FK ismi eşleşirse, eğer birleşik bir birleşimin sorgusunun yanlış olup olmadığını tespit etmek de daha kolaydır.


+1: Bunlar bence zorlayıcı nedenler, karşı çıkan diğer cevaplar ise IDbeni ikna etmiyor.
phoog

Yanıt: "Kopyalama işlemi karmaşık bir sorgu oluşturmak için birleşiyorsa" - sorununuz kopyala ve yapıştır 'dır. Kopyala ve yapıştır işlemini durdurduğunuzda, car.id isimlendirmenin ne kadar uygun olduğunu göreceksiniz. FK'ye katılmak için car.mfg = mfg.id, car.color = color.id, car.model = model.id - çok basit ve LINQ'de yazdıklarınızla eşleşir.
alpav

30 birleştirme ile bir şeyler yazmayı deneyin ve neden bir antipattern olduğunu göreceksiniz.
HLGEM

Aliasing ilk ve en önemli nedendir - büyük karmaşık raporlar yaparken böyle bir baş ağrısıdır. Doğal birleşimler sadece tatlı bir ikramiyedir. Diğer cevapların bu noktaları görmezden gelmesi şaşırtıcı. Bazı örnekler eklemek, noktayı daha net hale getirecek ve bu cevabı olması gereken yere daha yükseğe çıkaracak.
Lulu

5

Bir tablodaki birincil anahtarın sütun adı olarak "id" yi kullanmamamın en önemli nedenini düşündüğüm yaklaşıma bazı cevaplar var: yani tutarlılık ve düşük belirsizlik.

Bununla birlikte, benim için temel fayda, özellikle orijinal gelişime dahil olmayan bakım programcısı tarafından gerçekleştirilmektedir. Person tablosundaki kimlik için "PersonID" adını kullandıysanız ve sürekli olarak bu adı yabancı anahtar olarak kullandıysanız, bu "PersonID" yi çıkarmadan hangi tabloların PersonID olduğunu belirlemek için şemaya karşı bir sorgu yazmak önemsizdir. yabancı bir anahtar olduğunda kullanılan addır. Unutma, doğru ya da yanlış, yabancı anahtar ilişkilerinin her zaman tüm projelerde uygulanmadığını.

Bir tablonun aynı tablonun iki yabancı anahtarına sahip olması gerekebilecek bir kenar durumu vardır, ancak bu gibi durumlarda orijinal anahtar adını sütunun soneki adı olarak koyardım, böylece bir joker karakter eşleşmesi,% PersonID, kolayca bulabilir bu örnekler de.

Evet, bunun çoğu, "id" değerine sahip olma ve onu her zaman "tableNameID" olarak kullanmayı bilme standardı ile gerçekleştirilebilir, ancak hem uygulamanın yürürlükte olduğunu bilmeyi hem de orijinal geliştiricilere daha az bir yolla devam etmelerini gerektirir. sezgisel standart uygulama.

Bazı insanlar daha uzun sütun adlarını yazmak için bazı ekstra tuş vuruşları gerektirdiğini belirtmiş olsa da, kodun yazılmasının programın aktif ömrünün sadece küçük bir kısmı olduğunu belirtmek isterim. Geliştirici tuş vuruşlarını kaydetmek hedefse, yorumlar asla yazılmamalıdır.

Yıllarca yüzlerce masa ile büyük projeleri sürdürmek için harcayan biri olarak, anahtarlar için tutarlı isimler tercih ederim.


Bir Companiesmasanın bir masaya 2 yabancı anahtarı olduğunu varsayalım Persons. Biri şirketin başkanını temsil ediyor; Diğeri şirketin saymanlığını temsil eder. Gerçekten sütunları çağırır mısın PersonID1ve PersonID2? Bu çok daha açıklayıcı olarak adlandırmak olacağını PresidentIDve TreasurerID. Ben çok daha kolay okumak için bulmak inner join Person AS Presidents ON Company.PresidentID = Presidents.IDdahainner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
phoog

1
Hayır. Örneğinizde muhtemelen ilişkinin niteliği hakkında ek bilgilerle birlikte ve arasında birçok kişiyle ilişkiye izin veren bir tablo CompanyOfficerveya CompanyPersontabloya sahip olabilirim . Ben içinde bunu uygulamaya olsaydı tablonun, ben sütun adlarını kullanmak ve ek tanımlayıcı eklerken adının * PersonID kısmını korumak için. CompanyPersonCompanyPresidentPersonIDTreasurerPersonIDinner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
Malachi

5

Birincil anahtar alan olarak Id kullanma uygulaması, her tabloya kimliğin eklendiği uygulamaya yol açar. Birçok tablo zaten bir kaydı benzersiz olarak tanımlayan benzersiz bilgilere sahiptir. Her tabloya eklediğiniz bir id alanı değil, birincil anahtar olarak THAT kullanın. İlişkisel veritabanlarının temellerinden biri budur.

Bu yüzden kimliği kullanmak kötü bir uygulamadır: kimliği çoğu zaman sadece otomatik olarak artan bir bilgi değildir.

aşağıdaki tabloları göz önünde bulundurun:

PK id | Countryid   | Countryname
    1 |         840 | United States
    2 |         528 | the Netherlands

Bu tabloda yanlış olan, kullanıcının başka bir satır eklemesini sağlamasıdır: 840 ülke kodu ile ABD. Sadece ilişkisel bütünlüğü bozdu. Elbette, tek tek sütunlarda benzersizliği uygulayabilirsiniz ya da zaten mevcut olan bir birincil anahtarı kullanabilirsiniz:

PK Countryid   | Countryname
           840 | United States
           528 | the Netherlands

Bu yolla sahip olduğunuz bilgileri ilişkisel veritabanı tasarımının merkezinde olan birincil anahtar olarak kullanırsınız.


1
Farklı sistemler arasında veritabanlarını taşımak zorunda kaldığınızda veya veritabanlarını bir araya getirme zevkine sahip olduklarında, insanların neden her tabloya genel bir anahtar sütun eklediklerini anlayacaksınız.
Cypher

1
Bu bazen böyledir, ancak benim deneyimlerime göre eşsiz benzersiz bir değişmez anahtarın olması oldukça nadirdir. Ancak örneğinizde bile, ülkeleri tanımlamak için anlamsız, benzersiz bir sayıya sahipsiniz, sadece veritabanınız tarafından değil, ISO tarafından tahsis edilen bir ülke.
KodlarInChaos

Ve şimdi ülke adı değiştiğinde, düzeltmek için tüm veritabanınız boyunca güncellemelisiniz. Basitçe bir yedek anahtar kullanmış olsaydınız ("..." id gibi), güncelleme önemsiz olurdu. Doğal anahtarlar harika - tamamen değişken olmadıklarında ve asla değişmediğinde. Bunun doğru olduğu çok az vaka var.
Gerrat

@Gerrat: Bir ülke adı değişirse, ISO 3166-1 sayısal kodu aynı kalır, yalnızca ISO 3166-1 alpha-2 ve alpha-3 kodları değişir. Bu, örneğin Burma / Myanmar ile oldu. Benzer şekilde, bir ülke bölgesini değiştirir ancak ismini korursa, ISO 3166-1 sayısal kodu değişir, ancak ISO 3166-1 alpha-2 ve alpha-3 kodları kalır. Bu, Güney Sudan'ın Sudan'dan ve Eritre'nin Etiyopya'dan ayrılmasıyla oldu. Doğu ve Batı Almanya yeniden birleştiğinde, Batı Almanya'nın alfa-2 ve alfa-3 kodlarını sakladılar ancak yeni bir sayısal kod aldılar. Ülkeler tamamen çözüldüğü veya dönüşdüğü zaman (düşün…
Jörg W Mittag

… 90'ların Balkan savaşlarının sonucu olarak), hem sayısal hem de alfa-2 ve alfa-3 kodları alıyorlar.
Jörg W Mittag

4

Her tablonun ilk sütun adı olarak 'id' yi kullanıyorum çünkü kullandığım çerçevelerin bir kuralı (Ruby on Rails, CakePHP), bu yüzden her zaman geçersiz kılmak zorunda kalmıyorum.

Bu benim için akademik sebepleri geçemez.


2

Doğru kullanıldığında kötü bir uygulama olduğunu sanmıyorum. Asla dokunmanız gerekmeyen "ID" adı verilen otomatik artan bir ID alanına sahip olmak ve uygulama için dostça bir tanımlayıcı kullanmak yaygındır. Bu gibi bir kod yazmak için biraz hantal from tableA a inner join tableB b on a.id = b.a_idolabilir ama bu kod uzak sıkışmış olabilir.

Kişisel bir tercih olarak, kimliği işletme ismiyle öneklendirmeye meyilliyim, ancak sadece Idtamamen veritabanı tarafından kullanılıyorsa kullanımı ile ilgili gerçek bir sorun görmüyorum .


İki otomatik tabloyu, özellikle bir otomatik artırma kimliği birincil anahtarını kullanarak asla birleştiremezsiniz. Yukarıdaki örnek, Tablo A'dan, a.id = b.table_a_id üzerindeki iç birleştirme tablosu Bb olacaktır.
Bill Leeper

Evet, demek istediğim buydu. Neredeyse öğle vakti ve enerjiye ihtiyaç var.
Wayne Molina

2

Kimlik yeterince yaygın, kimsenin kafasını karıştırmayacağını sanmıyorum. Her zaman masayı bilmek isteyeceksin. Tablo / takma ad eklemeden alan adlarını üretim koduna koymak kötü bir uygulamadır. Geçici sorguları hızlı bir şekilde yazabilmekle ilgileniyorsanız, kendi başınızasınız.

Umarım hiç kimse kimliğin ayrılmış bir kelime olduğu bir sql veritabanı geliştirmez.

CREATE TABLE CAR (ID);

Alan adı, birincil anahtar ve otomatik artışlarla, hepsi bir arada küçük 2 karakterlik pakette 1 ile başlayarak 1 ile ilgilenir. Oh, ve ben buna CARS diyecektim ama tuş vuruşlarından tasarruf edeceksek ve gerçekten CAR denilen bir masanın sadece birisinin olacağını düşünürse?


1
Bu, resmi ilişkisel teori bilgisinin neden önemli olduğunu gösterir, tablo adı tek bir satırın ne olduğunu gösterir. Tablo CarBir temsil Tableher yerde Rowtek bir bağı Car. İçeri girmek Cars, anlambilimi değiştirir ve formel ilişkisel teori temel prensiplerinin tam olarak anlaşılmadığını gösterir. Raylar, tehlikeli olacak kadar iyi tanıyan birisinin en iyi örneğidir .

2

Bu soru tekrar tekrar dövüldü, ancak benim de fikrimi ekleyeceğimi düşündüm.

  1. Her tablonun tanımlayıcısı olduğunu belirtmek için id kullanıyorum, bu yüzden bir tabloya katıldığımda ve birincil anahtara ihtiyacım olduğunda otomatik olarak birincil anahtara katılıyorum.

  2. İd alanı imzasız bir otomatik özdeyiş (değeri asla ayarlamak zorunda kalmayacağım ve negatif olamayacağım anlamına gelir)

  3. Yabancı anahtarlar için tablenameid (yine bir stil meselesi) kullanıyorum, ancak katıldığım birincil anahtar tablonun kimliği alanı, böylece tutarlılık sorguları her zaman kolayca kontrol edebildiğim anlamına geliyor

  4. kimliği de kısa ve tatlı

  5. Ek kurallar - tüm tablo ve sütun adları için küçük harf kullanın;


1

Dikkate alınması gereken bir diğer husus, birincil anahtar adının yabancı anahtar adından farklı olması durumunda, belirli üçüncü taraf araçlarının kullanılması mümkün değildir.

Örneğin, şemanızı Visio gibi bir araca yükleyemez ve doğru ERD'ler üretmesini sağlayamazsınız.


Yine de üçüncü parti aracın hatası olabilir. Sütun adlandırma kuralları, aracın incelemesi gereken gerçek yabancı anahtarların yerine geçmez.
Gerrat

1

Buradaki insanları hemen hemen her yönüyle kapsıyorum ama "kimliği" nin "tanımlayıcı" olarak okunmadığını ve okunmaması gerektiğini "kesinlikle" dizininin "olduğunu ve kesinlikle satırın kimliğini belirtmediğini veya tarif etmediğini eklemek istiyorum. (Burada yanlış ifadeler kullanmış olabilirim, lütfen yazdıysam beni düzeltin)

İnsanların tablo verilerini nasıl okuduğu ve kodlarını nasıl yazdıkları az ya da çok. Ben şahsen ve büyük olasılıkla bu daha sık gördüğüm en popüler yol, kodlayıcıların table.idsendika veya / veya birleşme yapmaları gerekmese bile tam referansı yazdıklarıdır. Örneğin:

SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>

Bu şekilde İngilizce’ye “Bana o arabanın rengini ve modelini ver” olarak çevirebilirsin. ve "Numara olarak tanımlanan o arabanın rengini ve modelini ver" olarak değil. Kimlik, arabayı hiçbir şekilde temsil etmiyor, sadece otomobilin dizini, seri numarası. Tıpkı bir diziden üçüncü elemanı almak istediğinizde olduğu gibi.

Bu yüzden eklemek istediğim şeyi özetlemek, bunun sadece bir tercih meselesi olduğu ve SQL okumanın açıklanan yolunun en popüler olduğu.

Yine de, ID'nin gerçekten tanımlayan bir dize olduğu (çok daha nadir bir örnek) gibi, bunun kullanılmadığı bazı durumlar vardır. Örneğin id = "RedFordMustang1970"ya da benzer bir şey. Umarım bunu en azından açıklayabilmek için bunu açıklayabilirim.

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.