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?
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?
Yanıtlar:
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 cars
kı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.
cars
-> car
. Tanrıya şükür - parmaklarımı kurtardınız). Çok derinden okuma.
cars
ve manufacturer
. Biri çoğul, diğeri değil. İnsanlar db'de seçim yapmak istiyorsa, seçilmesi gereken kötü uygulama budur.
Çü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
SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId
. id
Yıllardır kullandım ve gerçek bir sorun olarak tanımladığınız şeyi asla bulamadım.
SELECT manufacturer.id FROM ...
. Ortaya çıkan her zorluk id
çok kolay bir şekilde üstesinden gelinebilir, bu da sadece bir zevk meselesidir.
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.
"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
name
ve 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, ...
Bu iplik öldü ama IMO o eklemek istiyorum değil kullanarak Id
kötü bir uygulamadır. Id
Kolon ö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.
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 .
Gönderen data.stackexchange.com
BOOM, soru cevaplandı.
Şimdi öğretmenine SO'nun kötü veritabanı tasarımı uyguladığını söyle.
PostTypeId -> PostTypes.Id
:; AcceptedAnswerId -> Answers.Id
; OwnerUserId -> Users.Id
. Neden bu kadar kolay bir uygulama 'kötü' olarak kabul edilmeli?
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 cars
yazı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.id
select * from dudes inner join cars where dudes.carid = cars.id
Her masaya "ID" yapıştırmanın en iyi fikir olmadığı bir durum vardır: USING
eğer destekleniyorsa , anahtar kelime. MySQL'de sıklıkla kullanıyoruz.
Örneğin, fooTable
sütununda fooTableId
ve barTable
yabancı anahtarınız fooTableId
varsa, 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)
USING
Anahtar kelime postgres / mysql / sqlite veritabanı tarafından desteklenmektedir, kullanmak için bir gerekçe olarak diğer cevaplar listesinin bazı az yazar demektir id
ve nihayet benim sübjektif görüşüme göre daha okunabilir.
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. ID
geneldir.
id
tek 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.
table.id
bir id
alana atıfta bulunmak için kabul edilebilir bir yoldur . Alan adının tablo adı ile ön eklenmesi gereksizdir.
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.
ID
beni ikna etmiyor.
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.
Companies
masanı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 PersonID1
ve PersonID2
? Bu çok daha açıklayıcı olarak adlandırmak olacağını PresidentID
ve TreasurerID
. Ben çok daha kolay okumak için bulmak inner join Person AS Presidents ON Company.PresidentID = Presidents.ID
dahainner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
CompanyOfficer
veya CompanyPerson
tabloya 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. Company
Person
Company
PresidentPersonID
TreasurerPersonID
inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
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.
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_id
olabilir ama bu kod uzak sıkışmış olabilir.
Kişisel bir tercih olarak, kimliği işletme ismiyle öneklendirmeye meyilliyim, ancak sadece Id
tamamen veritabanı tarafından kullanılıyorsa kullanımı ile ilgili gerçek bir sorun görmüyorum .
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?
Car
Bir temsil Table
her yerde Row
tek 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 .
Bu soru tekrar tekrar dövüldü, ancak benim de fikrimi ekleyeceğimi düşündüm.
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.
İd alanı imzasız bir otomatik özdeyiş (değeri asla ayarlamak zorunda kalmayacağım ve negatif olamayacağım anlamına gelir)
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
kimliği de kısa ve tatlı
Ek kurallar - tüm tablo ve sütun adları için küçük harf kullanın;
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.
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.id
sendika 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.