SQL Server'da aynı sütunda birden çok yabancı anahtar kullanımı


10

SQL Server bir sütun üzerinde birden çok yabancı anahtar oluşturmama izin veriyor ve her seferinde sadece farklı bir ad kullanarak aynı nesneye başvuran başka bir anahtar oluşturabilirim. Temelde tüm anahtarlar aynı ilişkiyi tanımlamaktadır. Aynı sütunda tanımlanan birden çok yabancı anahtarın ve başka bir tabloda aynı sütuna başvuru yapmanın ne anlama geldiğini bilmek istiyorum. SQL Server'ın böyle bir şey yapmamıza izin vermesinin yararı nedir?

resim açıklamasını buraya girin

Yanıtlar:


12

Yalnızca ada göre farklılık gösteren gereksiz kısıtlamalara sahip olmanın hiçbir yararı yoktur. Benzer şekilde, yalnızca ada göre farklılık gösteren fazladan dizinlere sahip olmanın hiçbir yararı yoktur. Her ikisi de değer olmadan ek yük ekler.

SQL Server veritabanı motoru bunu yapmanızı engellemez. İyi kısıtlama adlandırma kısıtlama adlandırma kuralları (örn. FK_ReferencingTable_ReferencedTable), bu tür hatalara karşı korunmaya yardımcı olabilir.


17

SQL Server birçok aptalca şey yapmanıza izin verir.

Kendini referans alan bir sütunda yabancı bir anahtar bile oluşturabilirsiniz - her satır kendi üzerindeki kısıtlamayı karşılayacağından bunun asla ihlal edilemez olmasına rağmen.

Aynı ilişkide iki yabancı anahtar oluşturma yeteneğinin potansiyel olarak yararlı olacağı bir uç durum, yabancı anahtarları doğrulamak için kullanılan dizinin oluşturma zamanında belirlenmesidir. Daha iyi (yani daha dar) bir dizin daha sonra gelirse, bu, daha iyi dizine bağlı yeni bir yabancı anahtar kısıtlaması oluşturulmasına izin verir ve ardından orijinal kısıtlama, etkin kısıtlama olmadan herhangi bir boşluk olmadan düştü.

(Aşağıdaki örnekte olduğu gibi)

CREATE TABLE T1(
    T1_Id INT PRIMARY KEY CLUSTERED  NOT NULL,
    Filler CHAR(4000) NULL,
) 

INSERT INTO T1 VALUES (1, '');

CREATE TABLE T2(
    T2_Id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    T1_Id INT NOT NULL CONSTRAINT FK REFERENCES T1 (T1_Id), 
    Filler CHAR(4000) NULL,
)


ALTER TABLE T1 ADD CONSTRAINT
    UQ_T1 UNIQUE NONCLUSTERED(T1_Id) 


/*Execution Plan uses clustered index*/ 
INSERT INTO T2 VALUES (1,1) 

ALTER TABLE T2  WITH CHECK ADD  CONSTRAINT FK2 FOREIGN KEY(T1_Id)
REFERENCES T1 (T1_Id)    

ALTER TABLE T2 DROP CONSTRAINT FK

/*Now Execution Plan now uses non clustered index*/    
INSERT INTO T2 VALUES (1,1)    

DROP TABLE  T2, T1;

Ara dönem için bir kenara bırakılırken, her iki kısıtlama mevcutken, herhangi bir kesici uç her iki endekse karşı da geçerlilik kazanır.


Aynı boşluksuz kısıtlama güncellemesini sağlamak için bir işlem kullanılabilir mi? Bu işlem dışı yöntem belki de daha az kilitleme nedeniyle daha mı iyi?
binki

13

Aynı yabancı anahtar kısıtlamaları, yani aynı sütunlar üzerinde ve aynı tablo ve sütunlara gönderme yapmanın bir anlamı yoktur.

Aynı kontrolü 2 veya daha fazla kez yapmak gibi.


- Katılmıyorum. Birincil tablonun iki ayrı kontrole ihtiyacı olabilir. Aşağıdaki örnek gönderici ve alıcı tamamen farklıdır - stackoverflow.com/questions/40400483/…
trex

@trex farklı bir şeyden bahsediyorsun. Buradaki soru şöyle der: " Aynı sütunda tanımlanan birden fazla yabancı anahtarın kullanılmasının ne olduğunu ve başka bir tabloda aynı sütuna başvuruda bulunmak istiyorum ."
ypercubeᵀᴹ

@ ypercubeᵀᴹ - Anladım. Açıkça belirttiğiniz için teşekkürler
trex

6

Aynı sütunda 50 dizin oluşturabilir, ikinci bir günlük dosyası ekleyebilir, maksimum sunucu belleğini 20 MB olarak ayarlayabilirsiniz ... sadece tavsiye edilmeyen şeylere karşı kontroller eklemek için motorda ek yük oluşturmanın avantajını kullanın.


2

Mavi-yeşil bir şey gibi geliyor.

Maviden yeşile geçmeye başladığınızda, geçici olarak şeylerin fazladan kopyalarını oluşturmanız gerekir.

Yapmak istediğimiz şey geçici olarak ekstra bir yabancı anahtar oluşturmak CHECK WITH NOCHECKve ON UPDATE CASCADE ON DELETE SET NULL; bunun yaptığı, çalışan bir yabancı anahtardır, ancak anahtar oluşturulduğunda mevcut satırlar kontrol edilmez.

Daha sonra eşleşmesi gereken tüm satırları temizledikten sonra yeni yabancı anahtarı herhangi bir komut seçeneği olmadan (varsayılan CHECK WITH CHECKolarak istediğiniz şeydir) oluşturur ve geçici yabancı anahtarı bırakırız.

Yabancı anahtarı düşürdüyseniz ve yeniden oluşturduysanız, bazı çöp satırlarının sizin tarafınızdan kayabileceğini unutmayın.

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.