1

Temat: Klucz obcy

Mam dwie tabele odcinki, o schemacie: <numer, nazwa, zakończony>, gdzie numer to klucz główny, oraz tabele kierowcy, w której mam miedzy innymi atrybuty zawieszony i zawieszony_numer_odcinka, które oznaczają odpowiednio czy kierowca został zawieszony i na którym odcinku rajdu zawieszono kierowce.
Zatem naturalne jest, aby zawieszony_numer_odcinka był kluczem obcym i odnosił się do klucza numer w tabeli odcinki. Ale zawiesić kierowce może także administrator rajdu, wtedy też w polu zawieszony_numer_odcinka umieszczamy np wartość 0, jednak w tabeli odcinki nie ma odcinka o numerze 0 (bo administrator nie jest odcinkiem przecież), więc nie możemy wstawić tej wartości do pola zawieszony_numer_odcinka.
Czy istnieje jednak możliwość aby zawieszony_numer_odcinka był kluczem obcym i jednocześnie mógł przyjmować jakąś wybraną wartość (w tym przypadku 0), która nie znajduje się w tabeli do której ten klucz się odnosi? Taki klucz obcy z wyjątkiem?

Jeśli klucz obcy może odnosić się do dwóch rożnych tabel, to można utworzyć tabele admin z atrybutem id o wartości 0 i przy zawieszony_numer_odcinka napisać REFERENCES odcinki(numer), admin(id) ale z tego co zrozumiałem ze schematu polecenia CREATE TABLE nie można tego zrobić, nie jestem jednak tego pewien.

2

Odp: Klucz obcy

3

Odp: Klucz obcy

Trochę FAIL podejście aby opisywać coś w ten sposób.

Jeśli coś opisujesz atrybutami i chcesz walidować dane za pomocą kluczy obcych to niech tak zostanie. Nie róbmy nic na silę.
Jeśli admin moze zablokować i jest to kolejny atrybut opisujący to dodaj kolumnę. np: typem bool ;]

Trochę mi się to kłoci z relacyjnością w bazie :> Chyba ze idziemy w koncepcje bigtable smile

Możesz zrobić tak jak rski mówi ale wtedy TY musisz zadbać o spójność danych w bazie.

Pozdrawiam
Pawel Socha

4

Odp: Klucz obcy

Ale przecież w odcinku możesz mieć NULL'e. Chociażby coś takiego:

create table test (a integer, b integer, primary key (b));
create table test1 (c integer, d integer, Primary Key (c), foreign key (d) references test (b));
insert into test values (1,1);
insert into test1 values (1,1);
insert into test1 values (2,NULL);
 c |   d
---+--------
 1 |      1
 2 | [null]
(2 rows)

I jak widać działa. Wówczas zawieszeni nie na odcinku a przez admina będą mieli NULL'a. Dodatkowo jak będziesz chciał wiedzieć który admin możesz zrobić analogicznie dla uid'a danego użytkownika.
Zapewniona zarówno integralność jak i funkcjonalność.
Aha - i jeszcze jedno, może oczywiste ale często zapominane. Foreign Key nie musi kierować na Primary Key - wystarczy indeks typu UNIQUE, wiec w danych po drugiej stronie też mogą być NULL'e jakbyś łączył się do tabeli która ma dwie wartości i jedna lub obie mogą być NULL'ami.

Ostatnio edytowany przez orcus (2009-05-14 12:57:42)

--------------
Nigdy nie kluc sie z glupcem - ludzie moga nie dostrzec roznicy.