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.