Ne zaman bire bir ilişki kullanmalıyım?


92

Bu çaylak soru için üzgünüm, ancak veritabanınızdaki tablolarla bire bir ilişki kullanmak için herhangi bir gerçek ihtiyaç var mı? Gerekli tüm alanları tek bir tablo içinde uygulayabilirsiniz. Veriler çok büyük olsa bile SELECT, kullanmak yerine ifadede ihtiyaç duyduğunuz sütun adlarını numaralandırabilirsiniz SELECT *. Bu ayrılığa gerçekten ne zaman ihtiyacınız var?

Yanıtlar:


105

1 ila 0..1

  • Süper ve alt sınıflar arasındaki "1 ila 0..1", kalıtımı uygulamak için "ayrı tablolardaki tüm sınıflar" stratejisinin bir parçası olarak kullanılır .

  • Bir "1 ila 0..1", NULL olabilen alanlar tarafından kapsanan "0..1" kısmı ile tek bir tabloda gösterilebilir. Bununla birlikte, ilişki yalnızca birkaç "1 ila 1" satırla çoğunlukla "1 ila 0" ise, "0..1" bölümünü ayrı bir tabloya bölmek bazı depolama (ve önbellek performansı) avantajlarından tasarruf sağlayabilir. Bazı veritabanları, NULL'leri diğerlerine göre depolamada daha tasarrufludur, bu nedenle bu stratejinin uygulanabilir hale geldiği bir "kesme noktası" önemli ölçüde değişebilir.

1'e 1

  • Gerçek "1'den 1'e" veriyi dikey olarak bölümler, bu da önbelleğe alma için etkileri olabilir. Veritabanları tipik olarak önbellekleri ayrı alanlar düzeyinde değil, sayfa düzeyinde uygular; bu nedenle, bir satırdan yalnızca birkaç alan seçseniz bile, genellikle satırın ait olduğu sayfanın tamamı önbelleğe alınır. Bir satır çok genişse ve seçilen alanlar nispeten darsa, aslında ihtiyacınız olmayan birçok bilgiyi önbelleğe alırsınız. Böyle bir durumda, verileri dikey olarak bölümlemek yararlı olabilir, böylece yalnızca daha dar, daha sık kullanılan bölüm veya satırlar önbelleğe alınır, böylece önbelleğe daha fazla sayıda sığabilir ve önbelleği etkili bir şekilde "daha büyük" hale getirir.

  • Dikey bölümlemenin başka bir kullanımı da kilitleme davranışını değiştirmektir: veritabanları tipik olarak tek tek alanlar düzeyinde kilitleyemez, yalnızca tüm satırları kilitleyebilir. Sırayı bölerek, bir kilidin yalnızca bir yarısında gerçekleşmesine izin vermiş olursunuz.

  • Tetikleyiciler ayrıca tipik olarak tabloya özeldir. Teorik olarak sadece bir tablonuz olabilir ve tetikleyicinin satırın "yanlış yarısını" görmezden gelmesini sağlayabilirsiniz, ancak bazı veritabanları bir tetikleyicinin yapabilecekleri ve yapamayacakları için bunu kullanışsız hale getirebilecek ek sınırlamalar getirebilir. Örneğin, Oracle, değişim tablosunu değiştirmenize izin vermez - ayrı tablolara sahip olduğunuzda, bunlardan yalnızca biri mutasyona uğrayabilir, böylece diğerini tetikleyicinizden değiştirmeye devam edebilirsiniz.

  • Ayrı tablolar daha ayrıntılı güvenlik sağlayabilir.

Bu hususlar çoğu durumda önemsizdir, bu nedenle çoğu durumda "1'e 1" tablolarını tek bir tabloda birleştirmeyi düşünmelisiniz.


20

Bir tablodaki veriler birbiriyle ilişkiliyse, ancak diğeri tarafından tanımlanan varlığa 'ait' değilse, bu, onu ayrı tutmaya adaydır.

Ayrı verilerin başka bir varlıkla da ilişkilendirilmesi gerekiyorsa, bu gelecekte avantajlar sağlayabilir.


19

Bire iki tablo yerleştirirseniz, muhtemelen anlambilim sorunu yaşarsınız. Örneğin, her cihazın bir uzaktan kumandası varsa, cihazı ve uzaktan kumandayı bir takım özellikleriyle tek bir tabloya yerleştirmek kulağa pek hoş gelmez. Hatta belirli bir özelliğin cihaza mı yoksa uzaktan kumandaya mı ait olduğunu anlamak için zaman harcamanız gerekebilir.

Sütunlarınızın yarısının uzun bir süre boş kalacağı veya hiç doldurulmayacağı durumlar olabilir. Örneğin, bir arabanın birçok özelliği olan bir römorku olabilir veya hiç olmayabilir. Böylece kullanılmayan birçok özelliğe sahip olacaksınız.

Tablonuzda 20 öznitelik varsa ve bunlardan yalnızca 4 tanesi ara sıra kullanılıyorsa, tabloyu performans sorunları için 2 tabloya bölmek mantıklıdır.

Bu gibi durumlarda her şeyin tek masada olması iyi değildir. Üstelik 45 sütunlu bir tabloyla uğraşmak kolay değil!


17

2 sentim.

Hepimizin büyük bir uygulamada geliştiği bir yerde çalışıyorum ve her şey bir modül. Örneğin, bir userstablomuz var ve bir kullanıcı için facebook ayrıntılarını ekleyen bir modülümüz var, bir kullanıcıya twitter ayrıntıları ekleyen başka bir modül. Bu modüllerden birini çıkarmaya ve tüm işlevlerini uygulamamızdan kaldırmaya karar verebiliriz. Bu durumda, her modül 1: 1 ilişkileriyle kendi tablosunu global userstabloya ekler , örneğin:

create table users ( id int primary key, ...);
create table users_fbdata ( id int primary key, ..., constraint users foreighn key ...)
create table users_twdata ( id int primary key, ..., constraint users foreighn key ...)

13

Bunu kullanmak için en mantıklı zaman, yalnızca bu şekilde ilişkilendirilecek iki ayrı kavram olsaydı olurdu. Örneğin, bir Araba yalnızca bir geçerli Sürücüye sahip olabilir ve Sürücü aynı anda yalnızca bir araba sürebilir - bu nedenle Araba ve Sürücü kavramları arasındaki ilişki 1 ila 1 arasında olacaktır. Bunun, nokta.

Diğer bir neden, bir konsepti farklı şekillerde uzmanlaştırmak istemenizdir. Bir Kişi tablonuz varsa ve Çalışan, Müşteri, Hissedar gibi farklı Kişi türleri kavramını eklemek istiyorsanız - bunların her birinin farklı veri kümelerine ihtiyacı olacaktır. Aralarında benzer olan veriler Kişi tablosunda, uzman bilgileri Müşteri, Hissedar, Çalışan için özel tablolarda olacaktır.

Bazı veritabanı motorları çok büyük bir tabloya (birçok satır) yeni bir sütun eklemekte zorlanıyor ve orijinal tabloya eklenen yeni sütun yerine yeni sütunu içeren uzantı tablolarını gördüm. Bu, ek tabloların daha şüpheli kullanımlarından biridir.

Performans veya okunabilirlik sorunları için tek bir kavram için verileri iki farklı tablo arasında bölmeye de karar verebilirsiniz, ancak bu, sıfırdan başlıyorsanız oldukça özel bir durumdur - bu sorunlar daha sonra kendini gösterecektir.


5

pek sık değil.

biraz güvenlik uygulamanız gerekirse, bir miktar fayda bulabilirsiniz - böylece bazı kullanıcılar sütunlardan bazılarını görebilir (tablo1) ancak diğerlerini göremez (tablo2) ..

Tabii ki bazı veritabanları (Oracle) bu tür bir güvenliği aynı tabloda yapmanıza izin verir, ancak bazıları izin vermeyebilir.


5

Veritabanı normalizasyonundan bahsediyorsunuz. Bakımını yaptığım bir uygulamada düşünebildiğim bir örnek Items. Uygulama, kullanıcının birçok farklı türde öğeyi satmasına izin verir (ör. Envanter Öğeleri, Envanter Öğeleri, Hizmet Öğeleri, vb.). Her öğenin gerektirdiği tüm alanları tek bir Öğeler tablosunda saklayabilsem de, tüm öğeler için ortak olan alanları içeren bir temel Öğe tablosuna sahip olmak ve ardından her öğe türü için ayrı tablolar (yani Envanter, Envanter Dışı, vb.) yalnızca bu öğe türüne özel alanlar içeren. Daha sonra, madde tablosunun temsil ettiği belirli bir madde türü için bir yabancı anahtarı olacaktır. Belirli madde tabloları ile temel madde tablosu arasındaki ilişki bire bir olacaktır.

Aşağıda normalizasyonla ilgili bir makale var.

http://support.microsoft.com/kb/283878


3

Tüm tasarım sorularında olduğu gibi, cevap "duruma göre değişir" dir.

Dikkat edilmesi gereken birkaç nokta var:

  • Tablo ne kadar büyük olacak (hem alanlar hem de satırlar açısından)? Hem bakım hem de programlama açısından kullanıcılarınızın adını, şifresini daha az kullanılan diğer verilerle birlikte barındırmak sakıncalı olabilir.

  • Birleşik tablodaki kısıtlamalara sahip alanların yönetimi zaman içinde külfetli hale gelebilir. örneğin, bir tetikleyicinin belirli bir alan için etkinleşmesi gerekiyorsa, bu, alanın etkilenip etkilenmediğine bakılmaksızın tablodaki her güncellemede gerçekleşecektir.

  • ilişkinin 1: 1 olacağından ne kadar eminsiniz? Bu sorunun işaret ettiği gibi , işler hızla karmaşıklaşabilir.


3

Başka bir kullanım durumu şunlar olabilir: bazı kaynaklardan veri aktarabilir ve günlük olarak güncelleyebilirsiniz, örneğin kitaplarla ilgili bilgiler. Ardından, bazı kitaplarla ilgili verileri kendiniz eklersiniz. Daha sonra içe aktarılan verileri kendi verilerinizden başka bir tabloya koymak mantıklıdır.


2

Normalde pratikte iki tür 1: 1 ilişki ile karşılaşıyorum:

  1. IS-A ilişkileri, süper tip / alt tip ilişkileri olarak da bilinir. Bu, bir tür varlığın aslında başka bir varlık türü olduğu zamandır (Varlık A, Bir KuruluşB'dir). Örnekler:

    • Aynı şirket içinde Muhasebeci, Mühendis, Satış Temsilcisi için ayrı varlıkları olan kişi varlığı.
    • Widget, RawMaterial, FinishedGood vb. İçin ayrı varlıklara sahip öğe varlığı.
    • Kamyon, Sedan vb. İçin ayrı varlıklara sahip otomobil varlığı.

    Tüm bu durumlarda, süper tip varlığı (örneğin Kişi, Öğe veya Araba) tüm alt tipler için ortak olan niteliklere sahip olacaktır ve alt tip varlıkları her bir alt tip için benzersiz niteliklere sahip olacaktır. Alt tipin birincil anahtarı, süper tipin anahtarıyla aynı olacaktır.

  2. "Patron" ilişkileri. Bu, bir kişinin bir organizasyon biriminin (departman, şirket vb.) Benzersiz patronu veya yöneticisi veya amiri olduğu zamandır. Bir kuruluş birimi için yalnızca bir patrona izin verildiğinde, patronu temsil eden kişi varlığı ile kuruluş birimi varlığı arasında 1: 1 ilişki vardır.


1
İkinci örneği beğendim. Varlık "Departman" ve "Çalışan" varlığınız olabilir. Bir departmanda birçok çalışanınız var ve bir çalışan yalnızca bir departmanda çalışabilir. Bu 1: n. Bir çalışan, bir departmanın amiri olabilir - sadece bir departmanın ve departmanın sadece bir süpervizörü vardır. Böylece, iki ilişkiyle bağlantılı iki tablo elde edersiniz - 1: n ve 1: 1.
Cezar

2

Birincisi, ayrı bir varlığı neyin oluşturduğunu modelleme ve tanımlama meselesi olduğunu düşünüyorum. Diyelim ki customersbir ve sadece bir single'ınız var address. Elbette her şeyi tek bir tabloda uygulayabilirsiniz customer, ancak gelecekte 2 veya daha fazla adrese sahip olmasına izin verirseniz, bunu yeniden düzenlemeniz gerekecektir (bir sorun değil, bilinçli bir karar verin).

Tabloyu bölmenin yararlı olabileceği diğer cevaplarda bahsedilmeyen ilginç bir durum da düşünebilirim:

Her birinde customersbirer tane olduğunu hayal edin, addressancak bu sefer bir adrese sahip olmak isteğe bağlıdır. Elbette bunu bir grup NULL-able sütun olarak uygulayabilirsiniz ZIP,state,street. Ama bunu verilen varsayalım var devlet isteğe bağlı değil bir adres, ancak Posta olduğunu. Bunu tek bir tabloda nasıl modelleyebilirim? customerTabloda bir kısıtlama kullanabilirsiniz , ancak başka bir tabloya bölmek ve foreign_key'i NULLable yapmak çok daha kolaydır. Bu şekilde, modeliniz varlığın address isteğe bağlı olduğunu ve ZIPo varlığın isteğe bağlı bir özniteliği olduğunu söylerken çok daha açıktır .


0

Programlama zamanımda bununla yalnızca bir durumda karşılaştım. Bu, aynı 2 varlık ("Varlık A" ve "Varlık B") arasında 1'den çoka ve 1'e 1 ilişkisinin olduğu zamandır.

"A Varlığı" birden fazla "Varlık B" ye sahip olduğunda ve "Varlık B" yalnızca 1 "Varlık A" ya sahip olduğunda ve "Varlık A" yalnızca 1 mevcut "Varlık B" ye ve "Varlık B" yalnızca 1 "Varlık A" ya sahip olduğunda.

Örneğin, bir Araba yalnızca bir geçerli Sürücüye sahip olabilir ve Sürücü aynı anda yalnızca bir araba sürebilir - bu nedenle Araba ve Sürücü kavramları arasındaki ilişki 1'e 1 olur. - Bu örneği @Steve Fenton'ın yanıtından ödünç aldım

Bir Sürücünün aynı anda değil, birden fazla Arabayı kullanabileceği yer. Dolayısıyla, Araba ve Sürücü varlıkları 1'den çoka veya çoktan çoğa şeklindedir. Ancak mevcut sürücünün kim olduğunu bilmemiz gerekirse, 1'e 1 ilişkisine de ihtiyacımız var.


0

Başka bir kullanım durumu, veritabanı tablosundaki maksimum sütun sayısının aşılması olabilir. O zaman OneToOne kullanarak başka bir masaya katılabilirsiniz

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.