Döngüsel bağımlılığı önlemek için bu veritabanı nasıl tasarlanır?


12

İki tablo vardır:

  1. kullanıcı
  2. Adres

Kullanıcı Adrese bir başvuru içeriyor.

Adres, Kullanıcıya referans olarak oluşturulan CreatedBy ve ModifiedBy sütunlarını içerir.

Döngüsel bağımlılığı önlemek için bu veritabanını nasıl tasarlayabilirim?


4
ModifiedBy uygulamasının kullanıcı (kullanıcı tablosunda bulunan) yerine, değişiklik yapan veritabanı kullanıcısına bir başvuru olmadığından emin misiniz? Her iki durumda da, gerçekten önemli değil. Neden gerçek bir sorun olduğunu anlamıyorum?
Philᵀᴹ

Hangisi önce yaratılacak. CreatedBy AND Modifiedby bir zorunluluk verisidir. Ve kullanıcı tablosunda null adres kimliği olmamalıdır .. Tavuk yumurtası sorunu. Ben kullanıcı kimliği ve addressid için referans içeren yeni bir tablo UserAddress oluşturarak bu çözmek gibi
Shashi

2
DBMS'niz destekliyorsa ertelenmiş kısıtlamaları her zaman kullanabilirsiniz.
Colin 't Hart

NB İlişkisel model, bir atomik işlem olarak iki ekleme veya güncelleme yapmayı destekler, bu SQL'de desteklenmeyen gerçek bir utançtır (ertelenmiş kısıtlamalar - önerdiğim halde - oldukça korkunçtur).
Colin 't Hart

Yanıtlar:


7

İpuçları ve püf noktaları aramak için (ertelenmiş kısıtlamalar dahil) Ben sadece bu "referans kilidi" çıkış yolu tasarlamanızı öneririz - bu yüzden böyle bir şey deneyin:


Gerçekler

  • Kullanıcı(UserID) var.
  • Adres Kullanıcı(AddressID) tarafından oluşturuldu .(UserID)
  • Adres(AddressID) oluşturulmuş tarihi(DateCreated) .
  • Adres(AddressID) son değiştiren edildi Kullanıcı(UserID) üzerine tarihi(ModifiedOn) .
  • Kullanıcı(UserID) de bulunduğu Adres(AddressID) beri tarihi(ValidFrom) .

Kısıtlamalar

  • Each Adres exactly one Kullanıcı tarafından oluşturuldu . It is possible that more than one Adres the same Kullanıcı tarafından oluşturuldu .

  • Each Adres oluşturulmuş exactly one tarihi . It is possible that more than one Adres oluşturulmuş the same tarihi .

  • For each Adres and tarihi , that adres tarafından değiştirildi at most one Kullanıcı üzerine that tarihi .

  • For each Kullanıcı and tarihi , that Kullanım bulunduğu at most one Adres beri that tarihi .


Mantıklı

resim açıklamasını buraya girin


Zorunlu adres söz konusu olduğunda, uygulama katmanında bunu doğrulayın ve yükleme deyimlerini bir işleme sarın - böylece tüm ya da hiçbir şeyi alamayacaksınız.


5

Aşağıdaki gibi 2 işlemde döngüsel bağımlılık oluşturmaktan başka bir seçeneğiniz yoktur, çünkü ilkini oluşturduğunuzda bir tablo yoktur.

CREATE TABLE A (A_ID INT PRIMARY KEY, B_FK INT);
CREATE TABLE B (B_ID INT PRIMARY KEY, A_FK INT REFERENCES A(A_ID));

ALTER TABLE A ADD B_FK INT;

Eğer döngüsel bağımlılıktan kaçınmak istiyorsanız. Daha sonra bir REFERENCES kısıtlamasını kaldırmanız veya bir şekilde bir DELETE ve UPDATE CASCADE referansı eklemeniz gerekir. Ayrıca mantığınız biraz karmaşıksa bir TRIGGER uygulayabilirsiniz.


1
Kısıtlamaları kaldırmak, döngüsel bağımlılığı tanımdan kaldırır, ancak tasarımdan kaldırır. Adresi en son oluşturan veya değiştiren, ancak bağımlılığı bir adım öteye taşıyan UserID ve AddressID değerlerini kaydetmek için bir Olaylar tablosu ekleyebilirsiniz. Diğer bir deyişle, Kullanıcı tablosunda CreatedBy ve ModifiedBy sütunları varsa, döngüsel bağımlılık bir tabloda var olur. Bu, süpervizörün aynı zamanda bir çalışan olduğu bir süpervizör sütununa sahip bir çalışan tablosuna benzer. Phil'in belirttiği gibi - Sorun değil.
Leigh Riffel

@LeighRiffel katılıyorum. Ancak, önerdiğiniz Etkinlikler tablosu aslında tüm döngüsel bağımlılıkları kaldırmaz.
ypercubeᵀᴹ

@ypercube Gerçekten de öyle; Bu teli nasıl geçtiğime emin değilim. Açık olmak gerekirse, döngüsel bağımlılığı kaldırsa bile, bir Etkinlikler tablosu oluşturmamalısınız.
Leigh Riffel

Her neyse, bu cevabın soruna hitap ettiğini düşünmüyorum. Soru (sanırım), ilk etapta döngüsel yolla FK'lerin nasıl oluşturulacağı değil, döngüsel yoldan nasıl kaçınılacağı ile ilgilidir.
ypercubeᵀᴹ
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.