60

Ich habe 2 Tabellen, wie Sie in meinem Posgresql-Code unten sehen werden. Die ersten Tabellenschüler haben 2 Spalten, eine für student_name und die andere student_id für den Primärschlüssel. In meiner zweiten Tabelle namens tests gibt es 4 Spalten, eine für subject_id, eine für den subject_name, dann eine für einen Studenten mit der höchsten Punktzahl in einem Fach, das höchsteStudent_id ist. Ich versuche, highestStudent_id auf student_id in meiner Schüler-Tabelle verweisen. Dies ist der Code, den ich unten habe, ist nicht sicher, ob die Syntax korrekt ist:postgresql Fremdschlüssel-Syntax

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 students korrekt? weil ich einen anderen wie highestStudent_id REFERENCES students(student_id)) gesehen habe

Was wäre die richtige Art der Erstellung des Fremdschlüssels in Postgresql bitte?

+4

Ja lautet die Syntax „korrigieren“. Die FK-Spalte sollte jedoch ** nicht ** als "seriell" definiert werden, sie sollte als "ganze Zahl" definiert werden. 'serial' ist kein" realer "Datentyp, es ist ein kurzer Zeiger zum Auffüllen des Defaultwertes aus der Sequenz –

+0

Wenn der FK einen Primärschlüssel referenziert, werden keine Spalten benötigt. Wenn der FK einen alternativen Schlüssel referenziert, werden Spalten benötigt. – jarlh

+0

@a_horse_with_no_name Meinst Du das so: highestStudent_id integer REFERENZEN players – Hamza

Antwort

118

Unter der Annahme, diese Tabelle:

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

Es gibt vier verschiedene Arten sind einen Fremdschlüssel (beim Umgang mit einem einzigen Spalte PK) und sie führen alle zum gleichen Fremdschlüssel zu definieren:

  1. Inline, ohne dass die Zielspalte zu erwähnen:

    CREATE TABLE tests 
    ( 
        subject_id SERIAL, 
        subject_name text, 
        highestStudent_id integer REFERENCES students 
    ); 
    
  2. I nline mit der Zielspalte zu erwähnen:

    CREATE TABLE tests 
    ( 
        subject_id SERIAL, 
        subject_name text, 
        highestStudent_id integer REFERENCES students (student_id) 
    ); 
    
  3. aus der Reihe innerhalb des 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 eigenständige alter table Aussage:

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

Welche Sie bevorzugen ist Geschmackssache. Aber Sie sollten in Ihren Skripten konsistent sein. Die letzten beiden Anweisungen sind die einzige Option, wenn Fremdschlüssel eine PK referenzieren, die aus mehr als einer Spalte besteht - Sie können den FK in diesem Fall nicht "inline" definieren, z. foreign key (a,b) references foo (x,y)

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


Der serial Datentyp ist nicht wirklich ein Datentyp. Es ist nur eine kurze Handnotation, die einen Standardwert für die Spalte aus einer Sequenz definiert. So dass jede Spalte Referenzierung eine Spalte definiert als serial muss mit dem entsprechenden Basistyp integer definiert werden (oder für bigintbigserial Spalten)

+0

danke für so detaillierte Erklärung. Ich weiß es wirklich zu schätzen und weiß jetzt, wie ich Referenzen zwischen meinen Tabellen erstellen und die richtigen Basistypen verwenden kann. Danke @a_horse_with_no_name – Hamza

+7

Für Ihr zweites Beispiel sollte es sein? hostestStudent_id integer REFERENZEN Studenten (student_id) 'anstelle von' higherStudent_id integer REFERENZEN Studenten (id) '? Oder ist "id" eine Art Kurzschrift? – John