sintassi della chiave esterna postgresql


122

Ho 2 tabelle come vedrai nel mio codice posgresql qui sotto. La prima tabella studenti ha 2 colonne, una per student_name e l'altra student_id che è la chiave primaria. Nella mia seconda tabella chiamata test, questa ha 4 colonne, una per subject_id, una per subject_name, quindi una per uno studente con il punteggio più alto in una materia che è più altaStudent_id. sto cercando di fare in modo che l'identificativo_studente si riferisca a id_allievo nella tabella degli studenti. Questo è il codice che ho di seguito, non sono sicuro che la sintassi sia corretta:

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

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

la sintassi è highestStudent_id SERIAL REFERENCES studentscorretta? perché ne ho visto un altro similehighestStudent_id REFERENCES students(student_id))

Quale sarebbe il modo corretto di creare la chiave esterna in postgresql, per favore?


4
Sì, la sintassi è "corretta". Tuttavia, la colonna FK non dovrebbe essere definita come serialdovrebbe essere definita come integer. serialnon è un tipo di dati "reale", è una
scorciatoia

Se FK fa riferimento a una chiave primaria, non sono necessarie colonne. Se il FK fa riferimento a una chiave alternativa, sono necessarie le colonne.
jarlh

1
La tua chiave esterna fa riferimento alla tabella "giocatori". Sembra che tu non abbia un tavolo chiamato "giocatori".
Mike Sherrill 'Cat Recall'

@Mike Sherrill 'Cat Recall mi dispiace, il mio errore volevo dire più altoStudent_id integer REFERENZE studenti
Hamza

Risposte:


250

Supponendo questa tabella:

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

Esistono quattro modi diversi per definire una chiave esterna (quando si ha a che fare con una singola colonna PK) e tutti portano allo stesso vincolo di chiave esterna:

  1. Inline senza menzionare la colonna di destinazione:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students
    );
  2. In linea con la menzione della colonna di destinazione:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
  3. Fuori linea all'interno di 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. Come alter tabledichiarazione separata :

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

Quale preferisci è una questione di gusti. Ma dovresti essere coerente nei tuoi script. Le ultime due istruzioni sono l'unica opzione se hai chiavi esterne che fanno riferimento a un PK che consiste di più di una colonna - non puoi definire il FK "inline" in quel caso, ad es.foreign key (a,b) references foo (x,y)

Solo le versioni 3) e 4) ti daranno la possibilità di definire il tuo nome per il vincolo FK se non ti piacciono quelli generati dal sistema da Postgres.


Il serialtipo di dati non è realmente un tipo di dati. È solo una notazione a mano breve che definisce un valore predefinito per la colonna presa da una sequenza. Quindi qualsiasi colonna che fa riferimento a una colonna definita come serialdeve essere definita utilizzando il tipo di base appropriato integer(o bigintper le bigserialcolonne)


Questo link ( postgresqltutorial.com/postgresql-foreign-key ) mostra un altro modo per fare ciò che hai detto che può essere fatto solo con il comando "constraint" in 3 e 4. Inoltre, che ne dici di mettere FOREIGN KEY prima dell'FK? Sembra che quando lo facciamo, non dobbiamo dichiarare il tipo di variabile?
parole per il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.