Postgresql-Fremdschlüsselsyntax

122

Ich habe 2 Tabellen, wie Sie in meinem posgresql-Code unten sehen werden. Die erste Tabelle Schüler hat 2 Spalten, eine für student_name und die andere student_id, die der Primärschlüssel ist. In meiner zweiten Tabelle mit dem Namen tests enthält diese 4 Spalten, eine für subject_id, eine für subject_name und eine für einen Schüler mit der höchsten Punktzahl in einem Fach, das die höchste Student_id ist. Ich versuche, die höchsteStudent_id in meiner Schülertabelle auf student_id zu verweisen. Dies ist der Code, den ich unten habe. Ich bin mir nicht sicher, ob die Syntax korrekt ist:

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

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

Ist die Syntax highestStudent_id SERIAL REFERENCES studentskorrekt? weil ich noch einen gesehen habehighestStudent_id REFERENCES students(student_id))

Was wäre der richtige Weg, um den Fremdschlüssel in postgresql zu erstellen?

Hamza
quelle
4
Ja, die Syntax ist "korrekt". Die FK-Spalte sollte jedoch nicht so definiert werden, wie serialsie definiert sein sollte als integer. serialist kein "echter" Datentyp, sondern eine kurze Hand zum
Auffüllen
Wenn der FK auf einen Primärschlüssel verweist, werden keine Spalten benötigt. Wenn der FK auf einen alternativen Schlüssel verweist, werden Spalten benötigt.
Jarlh
1
Ihr Fremdschlüssel verweist auf die Tabelle "Spieler". Sie scheinen nicht zu haben eine Tabelle mit dem Namen „Spieler“.
Mike Sherrill 'Cat Recall'
@ Mike Sherrill 'Cat Recall Entschuldigung, mein Fehler, ich meinte höchsteStudent_id Ganzzahl REFERENZEN Studenten
Hamza

Antworten:

249

Angenommen, diese Tabelle:

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

Es gibt vier verschiedene Möglichkeiten, einen Fremdschlüssel zu definieren (wenn es sich um eine einzelne Spalten-PK handelt), und alle führen zu derselben Fremdschlüsseleinschränkung:

  1. Inline ohne Erwähnung der Zielspalte:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students
    );
  2. In Übereinstimmung mit der Erwähnung der Zielspalte:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
  3. Außerhalb der Linie innerhalb der 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. Als separate alter tableAussage:

    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);

Welches Sie bevorzugen, ist Geschmackssache. Sie sollten jedoch in Ihren Skripten konsistent sein. Die letzten beiden Anweisungen sind die einzige Option, wenn Sie Fremdschlüssel haben, die auf eine PK verweisen, die aus mehr als einer Spalte besteht. In diesem Fall können Sie die FK "inline" nicht definieren, zforeign key (a,b) references foo (x,y)

Nur Version 3) und 4) geben Ihnen die Möglichkeit, Ihren eigenen Namen für die FK-Einschränkung zu definieren, wenn Sie die vom System generierten Namen von Postgres nicht mögen.


Der serialDatentyp ist eigentlich kein Datentyp. Es ist nur eine kurze Notation, die einen Standardwert für die Spalte aus einer Sequenz definiert. Daher muss jede Spalte, die auf eine als serialdefinierte Spalte verweist , unter Verwendung des entsprechenden Basistyps integer(oder bigintfür bigserialSpalten) definiert werden.

ein Pferd ohne Name
quelle
Dieser Link ( postgresqltutorial.com/postgresql-foreign-key ) zeigt eine andere Möglichkeit, das zu tun, was Sie gesagt haben. Dies kann nur mit dem Befehl 'beschränkung' in 3 und 4 durchgeführt werden. Es sieht so aus, als müssten wir dabei den Variablentyp nicht deklarieren?
Worte für den