SQL Server'da bir tabloda birden çok boş değer atanabilir FK'ye sahip olmak kötü bir uygulama olarak kabul edilir mi


13

SQL Server'daki veritabanı yapımda, sipariş hakkında farklı bilgiler gerektiren 3 çeşit ürünüm var. Yani, bir oluşturulmuş Customersmasa ve üç farklı emir tabloları: OrdersForProductAs, OrdersForProductBs, OrdersForProductCs. Tüm siparişler tablosunda bir ila birçok ilişki vardır Customers.

Ayrıca Payments, ödeme ayrıntılarını içeride tutacak başka bir tablom var. Ama burada nasıl yapılandırılacağı konusunda şüphelerim var.

Birden fazla ürün türüm olduğundan ve bir müşterinin aynı anda birden fazla ürün için siparişleri olabileceğinden, bu üç sipariş tablosunu Paymentstabloyla ilişkilendirmem gerekiyor .

Diğer sorun, bir müşterinin yalnızca bir tür ürün için sipariş verebilmesidir. Bu nedenle, Paymentstablodaki FK sütunlarının olması gerekir nullable.

Sorum şu: Bu nullableFK sütunlarının uzun vadede benim için baş ağrısı olup olmayacağı? Genel olarak konuşursak, bir masada boş değer FK sütunları olması kötü bir uygulama olarak kabul edilir mi?


2
Bu FK'lerden en az birinin boş kalmaması için bir kontrol kısıtlaması eklediğinizden emin olun .
Damien_The_Unbeliever

3
Sıfırlanabilir yabancı anahtarlardan biri çok fazla.
nvogel

Yanıtlar:


13

Neden OrdersForProductXtüm masalarınız
olduğunu soruyorum. Sorduğunuz FK sorununun tasarlanması mümkün ...

Bu tablolar aynı yapıya sahipse ProductType, bazı OrderProducttablolarda bir sütuna ihtiyacınız vardır . Sonra Paymentsadece bir FK ile bağlantı

Tablonun farklı yapıları varsa, bazı ortak özelliklere sahip olduklarını varsayıyorum. Böylece, ortak bir OrderProducttablonuz olabilir, ardından ürün tipi başına belirli bir çocuk tablonuz olabilir (aşağıya bakın) Yine, Paymentsadece bir FK ile ortak tabloya bağlantılar

Bu "superkey / alt tip modeli"

  • UQ1 "süper anahtar" alt tip tablolarda yabancı anahtar kullanılan
  • Her alt tür tablosunda bir bileşik PK ve FK bulunur (OrderID, ProductType)
  • Her alt tür tablosunun, o tablodaki türleri kısıtlamak için bir CHECK kısıtlaması vardır

OrderProduct

  • OrderID, PK, UQ1
  • ProductType, UQ1
  • CommonThing1
  • ...

OrderProductA

  • OrderID, PK, FK
  • ProductType, PK, FK, CHECK ProductType = A
  • ProductAThing1
  • ...

OrderProductB

  • OrderID, PK, FK
  • ProductType, PK, FK, CHECK ProductType = B
  • ProductBThing1
  • ...

4
@tugberk: NULLBu yaklaşımla FK sütununuz olmayacağına dikkat edin .
ypercubeᵀᴹ

"Bu tablolar aynı yapıya sahipse" Aynı yapıya sahip değillerdir.
tugberk

5

Null olabilecek "yabancı anahtarlardan" kaçının. Birden fazla dezavantajları vardır.

Yabancı anahtar bir null içerdiğinde, bir başvuru satırındaki kısıtlama her zaman uygulanmaz. Ancak, bu varsayılan davranış farklı DBMS'ler arasında tutarlı değildir. Bazı DBMS'ler, boş değerli yabancı anahtarların davranışını değiştirmek için yapılandırma seçeneklerini destekler, bazıları ise değiştirmez. Bu nedenle SQL geliştiricileri ve kullanıcıları, boş bir yabancı anahtar kısıtlamasının gerçekte veri bütünlüğü açısından ne anlama geldiği konusunda belirsiz olabilirler. Veritabanını DBMS ürünleri arasında veya hatta aynı ürünü kullanan farklı sunucular arasında taşımak, tutarsız sonuçlar verebilir.

Veritabanı tasarım araçları, entegrasyon araçları ve diğer yazılımlar bunları her zaman doğru şekilde desteklemez ve ürettikleri sonuçlar yanlış olabilir.

Yabancı anahtarlar birleştirmelerde ve diğer sorgu mantığında sıkça kullanılır ve kısıtlamanın geçerli olmadığında veya DBMS'niz tarafından uygulanan mantığı bilmeyen kullanıcılar için sorunları birleştirir.

Yabancı anahtar geçersiz kılındığında sorgu yeniden yazmalarına ve diğer optimizasyonlara izin veren bazı sorgu optimizasyon özellikleri kullanılamayabilir.

Mantıksal olarak, boş değerli bir "yabancı anahtar" kısıtlaması pek mantıklı değildir. SQL standardına göre, başvurulan tablo boş olsa bile böyle bir kısıtlama ihlal edilemez. Bu, null kullanmanın en yaygın iddia edilen gerekçelerinden biri ile çelişir - "bilinmeyen" vakayı temsil eder. Geçerli bir X değeri yoksa, herhangi bir "bilinmeyen" X kesinlikle geçerli bir değer olamaz - ancak SQL buna izin verir.

Sıfırlanabilir yabancı anahtarlar tamamen gereksizdir. Yabancı anahtarı her zaman yeni bir tabloya ayırabilir veya null'lara gerek kalmaması için bir süper tip / alt tip deseni kullanabilirsiniz. Basitlik ve doğruluk açısından null'ları dışarıda bırakmaktan daha iyidir.


2

Sıfırlanabilir FK sütunları kullanmanın kötü bir uygulama olarak değerlendirildiğini hiç duymadım. Başka bir tabloya başvuran ancak doldurulmayabilecek bir sütun için ideal bir seçimdir (yani isteğe bağlı veriler).

(Neden bir sorun olacağını düşünüyorsun?)


Teşekkürler! Bundan tam olarak emin değilim ama birkaç yıl önce böyle bir projem vardı ve bir şey üzerinde başım ağrıyor . Yani, gördüğünüz gibi net değilim: soruyu neden sordum.
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.