Kavşak tablosu oluşturmak yerine boş değerli bir yabancı anahtar kullanmanın dezavantajları


15

Aşağıdaki ER diyagramım olduğunu varsayalım:

resim açıklamasını buraya girin

Ben bir yabancı anahtar kullanarak ilişkiyi temsil Şimdi eğer Schooliçinde Student, anlatabilirdim NULL(a çünkü değerleri Student bir ait için gerekli değildir School, örneğin):

resim açıklamasını buraya girin

Yani (okuduğum şeye göre) doğru yol, ilişkiyi temsil etmek için bir kavşak tablosu oluşturmaktır, örneğin:

resim açıklamasını buraya girin

Bu şekilde, NULLtabloda hiçbir değer bulunamaz School_has_Student.

Ancak kesişim tablosu oluşturmak yerine boş değerli bir yabancı anahtar kullanmanın dezavantajları nelerdir?


Düzenle:

Yanlışlıkla ilişkiyi çoktan çoğa yapan tablonun birincil anahtarı olmayı seçtim ( school_id, student_id) School_has_Student. Doğru birincil anahtar şu olmalıdır student_id:

resim açıklamasını buraya girin


7
"Doğru" bir yol yoktur. İhtiyaçlarınız için en iyi yol var.
MetaFight

1
Doc ile yanlış öneri konusunda hemfikirim, ama belki de hala cevap verecek kadar açık mı?
MetaFight

Yanlış bir öneri var, ancak farkı düzeltmek ve açıklamak yeterince kolaydır.

Yakın oyumu geri çektim, ama cümle "Bu yüzden doğru yol (okuduğum şeye dayanarak) ilişkiyi temsil etmek için bir kavşak tablosu oluşturmaktır" bana hangi strainge kaynağının size bunun olduğunu söylediğin izlenimini veriyor. doğru yol. Daha önce okuduğum her ders kitabında, 1: n ilişkileri için kanonik yol tek bir yabancı anahtardır. Yoksa bir şeyi yanlış mı anladınız?
Doc Brown

@Doc Brown Nerede okuduğumu hatırlamıyorum, ancak kesişim tablosunun doğru yol olduğunu söylediğinden eminim. Her neyse, bana 1: n ilişkisinin (: 1 tarafında isteğe bağlı katılımla) tek bir yabancı anahtar kullanılarak temsil edilmesi gerektiğini söyleyen bir kitabın adını verebilir misiniz, bu konuda söylediklerini okumakla ilgileniyorum.
Tom

Yanıtlar:


18

İki model farklı ilişkileri temsil eder.

Birleştirme tablosu kullanarak, çoktan çoğa ilişkiyi modellersiniz.

Basit bir yabancı anahtar kullanarak, bire çok ilişkisini modellersiniz.

Sıfırlanabilir bir yabancı anahtarın dezavantajı, başarmaya çalıştığınız buysa, ilişkiyi çoktan çoğa kadar modelleyememektir.


Soruya yaptığınız düzenlemeye dayanarak, öğrenci tablosunu aynı anahtarla iki tabloya etkili bir şekilde ayırıyorsunuz. Bunu genellikle çok fazla alanı olan tablolarda görüyorum, bu yüzden birisi onları daha yönetilebilir olmak için ikiye böler (buna bir domuza ruj koyarak diyorum).

Öğrenci tablosunu bölerek ikinci tabloyu isteğe bağlı hale getirirsiniz çünkü ikinci tabloda bir kaydın bulunması gerekmez. Bu, ayarlanmasına gerek olmayan bir alana çok benzer çünkü boş olabilir.

Bire çok ilişki istiyorsanız, tek bir tablo kullanmaktan ve okul kimliğinin öğrenci tablosunda boş olmasına izin vermekten çok daha iyidir. Yabancı bir anahtar için bile, alanlardaki boş değerlerden kaçınmak için hiçbir neden yoktur. Bu, dış ilişkinin isteğe bağlı olduğunu gösterir: geliştiriciler ve DBA'lar bunu açıkça anlar ve temeldeki veritabanı motorunun kesinlikle iyi çalışması gerekir.

Eğer birleşimler konusunda endişeleriniz varsa, endişelenmeyin. Birleştirmelerin boş alanlarla nasıl çalıştığına dair iyi tanımlanmış semantikler vardır. Tek bir tablo kullanarak, üç yerine iki tabloyu birleştirebilirsiniz.


Bu yüzden bire-çok ilişkiyi modelleyeceksem (1 tarafında isteğe bağlı katılımla), NULLdeğerlere sahip olabilmesine rağmen yabancı bir anahtar kullanmalıyım ?
Tom

1
@Tom evet, tam olarak nasıl modellenir. Birleştirme tablosu kullanmak teknik olarak mümkün olsa da, veri modeli birçok kişiye izin verir, böylece bunu önlemek için tetikleyicilere ve veritabanı mantığına ihtiyacınız olacaktır. İlişkiyi yanlış veri eklemek imkansız olacak şekilde kısıtlayarak daha iyi durumdasınız.

1
Sorumu düzenledim. Tabloda sadece bire çok olarak ilişkiyi sürdüren student_idbirincil bir anahtar yaptım School_has_Student. Bu yöntemin yabancı anahtar kullanmanın getirdiği dezavantajları nelerdir?
Tom

@Tom cevabımı düzenledim.

6

Yukarıdaki bir yorumda yazdınız:

"Veritabanı Sistemlerinin Temelleri" [...] diyor ki [...], yabancı anahtar sütununda çok fazla NULL değer varsa (örneğin: çalışanların% 98'i varsa) bir kesişim tablosu kullanılması önerilir. bir departmanı yönetme)

Yabancı anahtar sütununda çok sayıda NULL değer olduğunda, programlarınızın işledikleri her kayıt için bu çoğunlukla boş sütunla uğraşması gerekecektir. Sütun, tüm vakaların% 98'inde boş olsa bile, muhtemelen biraz disk alanı kaplar, ilişkiyi sorgulamak, size daha fazla ağ trafiği veren sütunu sorgulamak anlamına gelir ve tablolarınızdan sınıflar üreten bir ORM kullanıyorsanız, programlarınız ayrıca müşteri tarafında gerekenden daha fazla alana ihtiyaç duyacaktır. Bir kesişim tablosu kullanmak bunu önler, yalnızca eşdeğer yabancı anahtarın NULL olmayacağı durumlarda gerekli olan bağlantı kayıtları olacaktır.

Buna karşılık, sadece birkaç NULL değeriniz yoksa,% 50 veya daha fazla ilişkinin NULL olmadığını söyleyelim, bir kesişim tablosu kullanmak size tam tersi etki sağlar - daha fazla disk alanı, daha fazla ağ trafiğine yol açan daha yüksek karmaşıklık vb.

Dolayısıyla, bir kesişim tablosu kullanmak sadece belirli bir durum için ve özellikle disk alanı ve belleğin daha ucuz hale geldiği, daha az sıklıkla ihtiyaç duyulduğu bir optimizasyon şeklidir. "Veritabanı Sistemlerinin Temelleri" nin 20 yıldan uzun bir süre önce yazılmış olduğunu unutmayın (1994'ün ikinci baskısına bir referans buldum) ve sanırım o zamanlar bu öneri zaten mevcuttu. 1994'ten önce, toplu depolama hala daha pahalı olduğundan ve bilgisayarlar ve ağlar bugünden çok daha yavaş olduğundan, alan optimizasyonu muhtemelen bugünden çok daha önemliydi.

Seçici bir yorumun yan notu olarak: yukarıdaki ifade sadece "Veritabanı Sistemlerinin Temelleri" nin yazarının önerisiyle aklından neler geçtiğini tahmin etmeye çalışıyor, sanırım çoğu sistem için geçerli, kaba, genel bir açıklama yapıyordu. Bazı veritabanlarında, bir kesişim tablosunun kullanımını daha da eski hale getiren "seyrek sütunlar" gibi başka olası optimizasyonlar da vardır.

Yani bu öneriyi yanlış anlamayın. Kitap, {0,1}:ngenel olarak ilişkiler için kavşak tablolarını tercih etmenizi veya yazdığınız gibi bunun "doğru yol" olduğunu söylemez . Programlarınızı yalnızca gerçekten ihtiyacınız olduğunda daha karmaşık hale getirecek bunun gibi optimizasyonları kullanın.


Özellikle OP'nin belirli bir veritabanından bahsetmediği düşünüldüğünde, veritabanının uygulanması hakkında çok şey varsayıyorsunuz. Veritabanının seyrek sütunlar için sadece az miktarda alan kullanacak kadar akıllı olması daha olasıdır.
gardenhead

@gardenhead: Bunun "olasıdan daha fazla" olduğuna inandığınız şey nedir?
Doc Brown

Veritabanlarının onlarca yıldır var olması ve çoğu altyapının kritik bir bileşeni olması nedeniyle oldukça optimize edilmiştir.
16:33 de gardenhead

@gardenhead: sesler bana göre benden daha fazla haksız varsayımlar yapıyorsun. Yine de, düzenlememe bakın.
Doc Brown

2

Kavramsal model , daha az söylemek çok alışılmadık bir şekilde şöyle görünecektir :

resim açıklamasını buraya girin

Fiziksel model şöyle görünecek , daha az söylemek kafa karıştırıcı (insanlar yakından görmedikçe M: M olduğunu düşünecekler):

resim açıklamasını buraya girin

Benim önerim:

Çoğu öğrenci için geçerli olmayan birçok sütununuz (FK veya başka türlü) varsa, tabloları 1: 1 makaralı rol tablolarına ayırın. Ancak bunun nedeni FK olmaları değil, sütunların çoğu satır için geçerli olmamasıdır.

Aksi takdirde , boş değerli FK bir veritabanının normal bir parçasıdır ve birleştirme tabloları genellikle M: ​​M rels içindir.

1: 1 halkaların yaygın kullanımları, yalnızca varlık belirli bir türdeyse geçerli olan ve performans veya depolama konuları için BLOB sütunlarını ayıklayan sütunlara sahip rol tabloları içindir. FK'lerde null değerlerden kaçınmak bunun için yaygın bir kullanım değildir.

resim açıklamasını buraya girin


2

Diğer cevaplara ek olarak, yabancı anahtar için sıfır değerinin belirsiz olduğunu belirtmek isterim. Anlamında mı:

1) Öğrencinin okulu (varsa) bilinmiyor (bu 'boş' standart anlamdır - değer bilinmiyor)

2) Öğrencinin bir okulu olup olmadığı bilinir ve hiçbir okulu yoktur.

Standart null anlamını kullanırsanız, yabancı anahtar modelinizde "öğrencinin okulu yok" u nasıl temsil edersiniz? Bu durumda, muhtemelen okul masasında kendi kimliği olan bir "okul yok" girişi oluşturmanız gerekir. (Uygun değil)


2
Kitap "Veri Tabanı Sistemlerinin Temelleri" için 3 yorumu vardır bahseder NULL, bu anlama gelebilir: 1) Bilinmeyen değer. 2) Kullanılamayan veya saklanan değer. 3) Geçerli olmayan özellik (Bence bu yorum NULLyabancı anahtar için bir belirtebileceğiniz anlamına gelir ).
Tom

1
Bu yararlı bir liste ancak null (veya gerçekten herhangi bir değer) anlambilimi kullanıcı tarafından tanımlanabilir. Yani, tasarımcının ne demek istediği anlamına gelebilir, bu listeyle sınırlı değildir. Mesele, birden fazla gerektiğinde farklı anlamların nasıl ayırt edileceğidir (hatta istenmeden kaydedilebilir)
Brad Thomas

Peki, boş bir yabancı anahtar kullanmak yerine bir kavşak tablosu oluşturmam gerektiğini mi söylüyorsunuz?
Tom

@Tom Evet, bu durumda daha iyi olduğuna inanıyorum
Brad Thomas

@BradThomas - bir kavşak tablosu kullanırken aynı belirsizliği önlemek için, NULL School_ID ile kavşak tablosundaki bir kayıtla vaka 2'yi (öğrencinin okula sahip olmadığı biliniyor) temsil eder misiniz?
andrew

1

Veritabanı tabloları kısıtlamalar denilen bu güzel şey var. Bu nedenle, her öğrencinin sadece 1'inin masada görünmesine izin veren kavşak tablosunda yapmak çok kolay, ancak o tabloda birçok okul. Size etkili bir şekilde

Teori güzel ama sonuçta sorduğunuz sorulardan sonra veritabanınızı modelleyeceksiniz.

"Hangi öğrencilerin okulumda olduğu" sorusunu sık sık sormak istiyorsanız, gerçekten tüm öğrenci tablosunu sorgulamak mı yoksa kolay bir kavşak tablosuna mı sahip olmak istiyorsunuz?

Veritabanlarında: sorduğunuz sorular için optimize edin.


0

Üçüncü bir tablo kullanmanın gerçekten mantıklı olabileceği bir kullanım durumu vardır. Örnek tamamen varsayımsal gibi görünebilir, ancak umarım benim amacımı iyi gösterir. Tabloya daha fazla sütun eklediğinizi varsayalım studentsve bir noktada, birkaç sütundaki bileşik dizin aracılığıyla kayıtlarda benzersizliği zorunlu kılmaya karar verdiniz. Büyük olasılıkla school_idsütunu da eklemeniz gerekecek ve burada işler dağınık olmaya başlıyor. Nedeniyle yol SQL birkaç özdeş kayıtları ekleme tasarlanmış school_idolan NULLmümkün olacaktır. Teknik açıdan mükemmel bir anlam ifade eder, ancak sezgiseldir ve beklenmedik sonuçlara yol açabilir. Öte yandan, kesişim tablosunda benzersizliği uygulamak kolaydır.

Son zamanlarda böyle bir "isteğe bağlı" ilişkiyi modellemek zorunda kaldım, burada bir teklik kısıtlaması gereksinimi bir zaman damgası sütununa bağlıydı. Sıfırlanabilir yabancı anahtarın tabloya bırakılması aniden aynı zaman damgasına sahip kayıtlar ekleme olasılığına yol açıyor (diyelim ki varsayılan değil, henüz denetlenmemiş / onaylanmamış kayıtlara ayarlanmış) - ve tek çıkış yolu boş sütun.

Gördüğünüz gibi, bu oldukça spesifik bir durum ve diğerlerinin de belirttiği gibi, çoğu zaman tüm NULLdeğerlerle mükemmel bir şekilde iyi olacaksınız . Gerçekten modelinizin özel gereksinimlerine bağlıdır.


0

Zaten sunulan birçok iyi öneriye ek olarak, gerçekten gerekli olmadıkça, şahsen yabancı anahtarların hayranı değilim. İlk olarak referansta bulunduğunuz M: M ilişkisi vardır. Ayrıca, yabancı bir anahtar çağırma ve böylece bu tablo verilerini sorgularınıza çekme, tablo boyutuna bağlı olarak daha yavaş performans sağlar. Diğerlerinin de söylediği gibi, boş değerli FK alanları desteklenmeyebilir ve veri bütünlüğü sorunları oluşturabilir.

Öğrenci okulunun bilinmediği veya boş olduğu bir eyalet tanımlıyorsanız, NULL bu koşulları ayırt etmeyecektir. (yine veri bütünlüğüne geri dönüyoruz.) Tulains'in rol tablosu önerisi zarif ve null değerleri temiz bir şekilde sağlıyor.

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.