Veritabanı tasarımı: Aynı tablo ile iki 1'den birçok ilişkiye


20

Ben her ikisi de 0, 1 veya birçok chequing hesabı olabilir iki farklı tablo Kişi ve Corporation ile ilgili olması gereken bir tablo Chequing_Account (bütçe, iban numarası ve hesabın diğer ayrıntılarını içeren) bir durum modellemek zorunda.

Başka bir deyişle, aynı tablo ile iki 1-çok ilişkim var Chequing hesabı

Bu sorun için normalleştirme gerekliliklerine uygun çözümler duymak istiyorum. Etrafımda duyduğum çoğu çözüm:

1) hem Person'in hem de Corporation'ın ait olduğu ortak bir varlık bulun ve bu ve Chequing_Account tablosu arasında bir bağlantı tablosu oluşturun, bu benim durumumda mümkün değildir ve bu sorunu değil, genel sorunu çözmek istesem bile.

2) İki varlığı Chequing Hesaplarıyla ilişkilendiren PersonToChequingAccount ve CorporationToChequingAccount olmak üzere iki bağlantı tablosu oluşturun. Ancak iki kişinin aynı chequing hesabına sahip olmasını istemiyorum ve bir chequing hesabını paylaşmak için gerçek bir kişi ve bir şirkete sahip olmak istemiyorum! bu resme bak

http://i41.tinypic.com/35i6kbk.png

3) Chequing Hesabında, Corporation ve Gerçek Kişiye işaret eden iki yabancı anahtar oluşturun, ancak bu nedenle bir Kişinin ve Şirketin birçok chequing hesabına sahip olabileceğini zorunlu kılmakla birlikte, her ChequingAccount satırı için her iki ilişkinin de Şirket ve gerçek kişi, çünkü bir çek hesabı ya bir şirket ya da gerçek bir kişidir. bu resme bak

http://i40.tinypic.com/1rpv9z.png

Bu sorunun daha temiz bir çözümü var mı?


Eğer örneğin bir için sahip düşündünüz mü OwnerTypeIDiçinde ChecquingAccountolan, masa 1=Corporationve 2=NaturalPerson? Eğer sadece bir ihtiyaç Böylece OwnerIDiçinde ChecquingAccountmasa, birlikte olabildiğince hangi indeks OwnerTypeID.
RoKa

Ben sadece bir şirket veya gerçek kişi olup olmadığını bilmek değil, aynı zamanda ilgili kimliği bilmek gerekir, bu yüzden bir kimlik numarası ve sadece 1 veya 2 bir değer gerekir! Çözüm 3, burada bulduğum şey, şirket veya gerçek kişi
kimliğine

2
Evet, çözüm geçerli bir seçenektir. Çoğu DBMS'de, iki FK'den sadece birinin bir kontrol kısıtlamasıyla "aktif" olduğunu uygulayabilirsiniz: CHECK (CorporationID IS NOT NULL AND NaturalPersonID IS NULL OR CorporationID IS NULL AND NaturalPersonID IS NOT NULL)1 numaralı çözümü tercih ederim (ama bu sadece ben). Çok "temiz".
ypercubeᵀᴹ

Evet anlıyorum, ama sen de olabilir ChecquingAccounttablonun rekor OwnerTypeID=1ve OwnerID=123bir türü olduğunu belirten Corporation, bu nedenle kimlik 123içinde Corporationtablonun. OwnerTypeID size hangi tabloyu, OwnerID ise o tablodaki kimliği söyler.
RoKa

1
1. seçenek nasıl imkansız? "Şirket" kelimesi temelde "yasal olarak bir kişi" anlamına gelir. Ona Customersmasa diyelim.
Tüm Ticaretlerden Jon

Yanıtlar:


15

İlişkisel veritabanları bu durumu mükemmel bir şekilde ele almak için inşa edilmemiştir. Sizin için neyin en önemli olduğuna karar vermeli, sonra da takaslarınızı yapmalısınız. Birkaç hedefiniz var:

  • Üçüncü normal formu koru
  • Referans bütünlüğünü koruyun
  • Her hesabın bir şirkete veya gerçek bir kişiye ait olduğu kısıtlamasını koruyun.
  • Verileri basit ve doğrudan alma yeteneğini koruyun

Sorun şu ki, bu hedeflerin bazıları birbiriyle rekabet ediyor.

Alt Yazma Çözümü
Hem şirketleri hem de kişileri içeren bir süper tür oluşturduğunuz bir alt yazma çözümü seçebilirsiniz. Bu süper-tip muhtemelen alt-tipin doğal anahtarının bir bileşik anahtarına ve bir bölümleme özelliğine (örneğin customer_type) sahip olacaktır. Bu normalleşmeye kadar iyidir ve referans bütünlüğünü ve kurumların ve kişilerin birbirini dışlayan kısıtlarını uygulamanızı sağlar. Sorun, customer_typehesabın hesabına ne zaman katıldığınıza bağlı olarak her zaman şube açmanız gerektiğinden, bu durum veri alımını zorlaştırır . Bu muhtemelen UNIONsorgunuzda çok sayıda tekrarlanan SQL kullanmak ve kullanmak demektir .

İki Yabancı Anahtar Çözümü
Hesap tablonuzda, biri şirkete diğeri de kişi olmak üzere iki yabancı anahtarı saklayabileceğiniz bir çözüm seçebilirsiniz. Bu çözüm aynı zamanda referans bütünlüğünü, normalleştirmeyi ve karşılıklı münhasırlığı korumanızı sağlar. Ayrıca, alt yazma çözümüyle aynı veri alma dezavantajına sahiptir. Aslında, bu çözüm, birleştirme mantığınızı "daha erken" dallandırma problemine girmeniz dışında, alt-yazma çözümü gibidir.

Bununla birlikte, birçok veri modelcisi, karşılıklı münhasırlık kısıtlamasının uygulanması nedeniyle bu çözümü alt yazma çözümünden daha düşük olarak değerlendirecektir. Alt yazma çözümünde, karşılıklı münhasırlığı uygulamak için anahtarları kullanırsınız. İki yabancı anahtar çözümünde bir CHECKkısıtlama kullanırsınız . Çek kısıtlamalarına karşı haksız önyargısı olan bazı insanlar tanıyorum. Bu insanlar, kısıtlamaları anahtarlarda tutan çözümü tercih ederler.

"Denormalized" Bölümleme Öznitelik Çözümü
Chequing hesap tablosunda tek bir yabancı anahtar sütunu tuttuğunuz ve yabancı anahtar sütununu nasıl yorumlayacağınızı söylemek için başka bir sütun kullandığınız başka bir seçenek daha var (RoKaOwnerTypeIDkolonu). Bu esas olarak alt tablolamadaki süper tip tabloyu, alt tabloya bölümleme niteliğini denormalize ederek ortadan kaldırır. (Bölümleme özniteliği birincil anahtarın bir parçası olduğu için bunun biçimsel tanıma göre kesinlikle "denormalizasyon" olmadığını unutmayın.) Bu çözüm, aynı şeyi yapmak için fazladan bir tabloya sahip olmaktan kaçındığı için oldukça basit görünüyor ve yabancı anahtar sütunlarının sayısını bire indirir. Bu çözüm ile sorunu alma mantığın dallanma önlemek etmez ve dahası, bu sürdürmek için izin olmamasıdır deklaratif bilgi tutarlılığı. SQL veritabanları, birden çok üst tablodan biri için olan tek bir yabancı anahtar sütununu yönetme yeteneğine sahip değildir.

Paylaşılan Birincil Anahtar Alan Adı Çözümü
İnsanların bazen bu sorunla ilgilenmesinin bir yolu, bir alt türe veya diğerine ait olsun, herhangi bir kimlik için karışıklık olmaması için tek bir kimlik havuzu kullanmaktır. Bu, bir banka senaryosunda doğal olarak işe yarayacaktır, çünkü hem bir şirkete hem de gerçek bir kişiye aynı banka hesap numarasını vermeyeceksiniz. Bunun avantajı, bir bölümleme özelliğine ihtiyaç duyulmamasıdır. Bunu süper tip bir tabloyla veya tablo olmadan yapabilirsiniz. Süper tür bir tablo kullanmak, benzersizliği zorunlu kılmak için bildirici kısıtlamalar kullanmanızı sağlar. Aksi takdirde, bunun usule uygun olarak uygulanması gerekir. Bu çözüm normalleştirilmiştir, ancak süper tür tablosunu tutmadığınız sürece bildirici başvuru bütünlüğünü korumanıza izin vermez. Hala karmaşık geri alma mantığından kaçınmak için hiçbir şey yapmıyor.

Bu nedenle, tüm kurallara uyan temiz bir tasarıma sahip olmanın ve aynı zamanda veri alımınızı basit tutmanın gerçekten mümkün olmadığını görebilirsiniz. Ödüllerinizin nerede olacağına karar vermelisiniz.


# 2 numaralı çözümüm, dört grubunuzdan hangisine ait? "Denormalized Partitioning Attribute Solution" benim için pek açık değil ..
dendini

@ dendini - 2 numaralı çözüm, özetlediğim çözümlerin hiçbirine uymuyor. Bunun nedeni, bir tüzel kişiye ait bir hesabın gerekliliğine uymamasıdır. Ara tabloların birincil anahtarlarını tanımlama şekliniz, bunlar çoktan çokya kesişimlerdir. Birincil anahtarlar olsaydı sadece corporation_id ve person_ido zaman aslında insanların birden fazla hesabı değil tutunabileceği, süper-tipi masa ikiye bölünmüş olurdu ve yabancı anahtar ters dönmüştür o hariç, alt yazarak çözüm olurdu. Bu tür bir amacı yener.
Joel Brown

Harika bir açıklama. @JoelBrown, sorgulama açısından "İki yabancı anahtar" çözümünün performans sonuçları nelerdir? Ayrıca, 2 yerine 6 veya daha fazla yabancı anahtar olabileceğini göz önünde bulundurursak: yine de bu yaklaşımı tavsiye eder misiniz yoksa farklı bir yönteme mi yaslanırsınız?
Amadeo Gallardo

1
@AmadeoGallardo Cevap "duruma bağlıdır". Bir anahtara karşı sorgulama her zaman oldukça verimlidir, çünkü genellikle bir arama olmasa bile en azından bir dizin taramasına güvenebilirsiniz ve bunlar hızlı işlemlerdir. Bu sorun, iki yabancı anahtar çözümünde her iki anahtarı da sorguladığınızda oluşur. Burada, sorgu optimize ediciden bir / veya işlem yapmasını istiyorsunuz. En iyi ihtimalle bu, genellikle biraz daha kötü olan sorgunun maliyetini iki katına çıkarır, çünkü bir tuşa, sonra diğerine karşı sorgulamak ve ardından sonuçları birleştirmek zorunda kalırsınız.
Joel Brown

@JoelBrown Normalleştirilmemiş gelecek SQL sürümleri iki sütun dayalı bir bileşik yabancı anahtarın tanımını izin vererek bu yaklaşımı izin vermelidir RefIDve RefTablenerede RefTablesabit id o tanımlar hedef tablodur. Bu tür anahtarlar için çok fazla kullanım durumu vardır ve bütünlüğü sağlamak için 10 veya daha fazla ilişkilendirme / alt tür tablosunu korumak çok fazladır. Bu durumlar için bunu keykendim yarattım .
djmj
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.