Bileşik yabancı anahtarların neden ayrı bir benzersiz kısıtlamaya ihtiyacı var?


10

Kayıtların aynı tablodaki üst kayıtlara başvurabileceği basit bir tablo:

CREATE TABLE foo (
    id         SERIAL  PRIMARY KEY,
    parent_id  INT     NULL,
    num        INT     NOT NULL,
    txt        TEXT    NULL,
    FOREIGN KEY (parent_id) REFERENCES foo(id)
);

Ek alan değerlerinden birinin ( num) ebeveyn ve alt kayıtlar arasında aynı olması şartıyla, bileşik bir yabancı anahtarın hile yapması gerektiğini düşündüm. Son satırı olarak değiştirdim

    FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)

ve HATA var : başvurulan tablo "foo" için verilen anahtarlarla eşleşen benzersiz bir kısıtlama yoktur .

Bu kısıtlamayı kolayca ekleyebilirim, ancak başvurulan sütunlardan ( id) zaten benzersiz olduğu garanti edildiğinde neden gerekli olduğunu anlamıyorum ? Gördüğüm gibi, yeni kısıt gereksiz olurdu.

Yanıtlar:


11

DBMS'nin bir sınırlaması - hepsinde bildiğim kadarıyla. Ve sadece bir sütun eklerken değil, aynı zamanda sütunları yeniden düzenlerken. Eğer bir UNIQUEkısıtlamamız varsa, esasen gereksiz olan benzersiz bir kısıtlama olmadığı sürece (a1, a2)bunu ekleyemeyiz .FOREIGN KEYREFERENCES (a2, a1)(a2, a1)

Bunu bir özellik olarak eklemek çok zor olmayacaktı:

Üzerinde bir UNIQUEkısıtlama olduğunda (a), herhangi bir kombinasyon (a, b, c, ..., z)veya (b,c, ...a, ...z)kombinasyon da garanti edilir UNIQUE.

veya genelleme:

Bir UNIQUEkısıtlama olduğunda (a1, a2, ..., aN), herhangi bir (a1, a2, ..., aN, b1, b2, ..., bM)kombinasyon veya herhangi bir yeniden düzenleme de garanti edilir UNIQUE.

Görünüşe göre sorulmamış veya uygulanacak kadar yüksek öncelik olarak görülmemiştir.

Özelliğin uygulanması için her zaman - ilgili kanalda - istekte bulunabilirsiniz. Ya da DBMS Postgres gibi açık kaynaksa kendiniz de uygulayabilirsiniz.


Bunun bu kadar basit olacağından emin değilim ... Kısmi dizinler veya NULL değerler ne olacak? vs .. NULL memnun iseniz yine de iyi çalışabilir NULL != NULL. Her neyse .. :)
Joishi Bodio

@JoishiBodio Nulls'ın bir sorun olduğunu düşünmüyorum. UNIQUE kısıtlamaları tanımlanabilir veya boşaltılabilir sütunlar da olabilir. Varsayılan, herhangi bir sütunda NULL varsa, kısıtlamanın geçirilmesi ve satırın kabul edilmesidir.
ypercubeᵀᴹ

İkinci olarak, eğer a1, a2, ... aN boş bırakılamazsa ve b1, b2, bM sorunlara yol açabilir. Ancak bu özellik, kesinlikle geçersiz olmayan sütunlar için uygulanabilir. Muhtemelen endişe verici olan şey verimlilik sonuçlarıdır.
ypercubeᵀᴹ

Ben UNIQUE INDEXsütunların nerede NULLABLEolduğunu biliyorum .. bu yüzden bahsettiğim. :) Ama katılıyorum - hiçbir NULL (ve kısmi bir dizin değil) durumunda, muhtemelen oldukça basittir.
Joishi Bodio

5

Yabancı anahtarlar genel olarak (sadece kompozit değil) başka bir tabloda bir tür benzersiz bir anahtar işaret gerekir ZORUNLU. Eğer olmasaydı, ilişkisel veri bütünlüğü olmazdı.

Bu, (id) üzerinde benzersiz bir anahtarınız varken (id, num) üzerinde benzersiz bir anahtarınız olmadığı için şikayetçi olur. Bu nedenle, DB söz konusu olduğunda, çift (id, num) benzersiz olmak için GARANTİLİ değil. Biz insanlar olarak, bunun benzersiz olacağını anlayabiliriz, ancak eminim Postgres'i "oh hey .. id benzersiz olması gerekiyordu." , yani id, num da benzersiz olmalı "..

Tüm yapmanız gereken sorunu çözmek için iki sütun üzerinde başka bir benzersiz dizin oluşturmak olduğunda bu kodu eklediyseniz çok şaşırırsınız.

Açık olmak gerekirse, eklemek zorunda oldukları kod sadece bu basit durum değil ... yabancı anahtarın 4+ sütun üzerinde olduğu durumlarda bile tüm durumları işlemek zorunda kalacaktı ... Eminim mantık oldukça karmaşık olurdu.

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.