Składnia klucza obcego postgresql


122

Mam 2 tabele, jak zobaczysz w moim kodzie posgresql poniżej. Pierwsza tabela uczniów ma dwie kolumny, jedną dla ucznia_nazwa, a drugą student_id, który jest kluczem podstawowym. W mojej drugiej tabeli o nazwie testy, zawiera ona 4 kolumny, jedną dla subject_id, jedną dla subject_name, a następnie jedną dla ucznia z najwyższym wynikiem z przedmiotu, który jest najwyższymStudent_id. próbuję, aby parametr najwyższyStudent_id odnosił się do student_id w tabeli moich uczniów. Oto kod, który mam poniżej, nie jestem pewien, czy składnia jest poprawna:

CREATE TABLE students ( student_id SERIAL PRIMARY KEY,
                 player_name TEXT);

CREATE TABLE tests ( subject_id SERIAL,
                   subject_name,
                   highestStudent_id SERIAL REFERENCES students);

czy składnia jest highestStudent_id SERIAL REFERENCES studentspoprawna? ponieważ widziałem inny podobnyhighestStudent_id REFERENCES students(student_id))

Jaki byłby poprawny sposób tworzenia klucza obcego w postgresql?


4
Tak, składnia jest „poprawna”. Jednak kolumna FK nie powinna być definiowana tak serial, jak powinna integer. serialnie jest „prawdziwym” typem danych, to krótka ręka do
— zapełnienia

Jeśli FK odwołuje się do klucza podstawowego, nie są potrzebne żadne kolumny. Jeśli FK odwołuje się do klucza alternatywnego, potrzebne są kolumny.
— jarlh

1
Twój klucz obcy odwołuje się do tabeli „graczy”. Wygląda na to, że nie masz stołu o nazwie „gracze”.
— Mike Sherrill „Cat Recall”

@Mike Sherrill 'Cat Recall, przepraszam, mój błąd chodziło mi o najwyższąStudent_id integer REFERENCES studenci
— Hamza

Odpowiedzi:


251

Zakładając tę ​​tabelę:

CREATE TABLE students 
( 
  student_id SERIAL PRIMARY KEY,
  player_name TEXT
);

Istnieją cztery różne sposoby definiowania klucza obcego (w przypadku pojedynczej kolumny PK) i wszystkie prowadzą do tego samego ograniczenia klucza obcego:

  1. W tekście bez wzmianki o kolumnie docelowej:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students
    );
  2. W wierszu ze wzmianką o kolumnie docelowej:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
  3. Poza linią wewnątrz create table:

    CREATE TABLE tests 
    ( 
      subject_id SERIAL,
      subject_name text,
      highestStudent_id integer, 
      constraint fk_tests_students
         foreign key (highestStudent_id) 
         REFERENCES students (student_id)
    );
  4. Jako osobne alter tableoświadczenie:

    CREATE TABLE tests 
    ( 
      subject_id SERIAL,
      subject_name text,
      highestStudent_id integer
    );
    
    alter table tests 
        add constraint fk_tests_students
        foreign key (highestStudent_id) 
        REFERENCES students (student_id);

Który wolisz, to kwestia gustu. Ale powinieneś być konsekwentny w swoich skryptach. Ostatnie dwie instrukcje są jedyną opcją, jeśli masz klucze obce odwołujące się do PK, który składa się z więcej niż jednej kolumny - nie możesz w takim przypadku zdefiniować „inline” FK, np.foreign key (a,b) references foo (x,y)

Tylko wersja 3) i 4) daje możliwość zdefiniowania własnej nazwy dla ograniczenia FK, jeśli nie podoba ci się te wygenerowane przez system z Postgres.


Typ serialdanych tak naprawdę nie jest typem danych. Jest to po prostu krótka notacja ręczna, która definiuje domyślną wartość kolumny pobraną z sekwencji. Zatem każda kolumna odwołująca się do kolumny zdefiniowanej jako serialmusi być zdefiniowana przy użyciu odpowiedniego typu podstawowego integer(lub bigintdla bigserialkolumn)


Ten link ( postgresqltutorial.com/postgresql-foreign-key ) pokazuje inny sposób zrobienia tego, co powiedziałeś, można zrobić tylko za pomocą polecenia „constraint” w 3 i 4. Ponadto, co z umieszczeniem KLUCZA OBCEGO przed FK? Wygląda na to, że kiedy to robimy, nie musimy deklarować typu zmiennej?
— słowa z
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.