syntaxe de clé étrangère postgresql

122

J'ai 2 tables comme vous le verrez dans mon code posgresql ci-dessous. La première table Students a 2 colonnes, une pour student_name et l'autre student_id qui est la clé primaire. Dans mon deuxième tableau appelé tests, il contient 4 colonnes, une pour subject_id, une pour subject_name, puis une pour un étudiant avec le score le plus élevé dans un sujet qui est le plus élevéStudent_id. J'essaie de faire en sorte que le plus hautStudent_id fasse référence à student_id dans ma table des étudiants. C'est le code que j'ai ci-dessous, je ne suis pas sûr que la syntaxe soit correcte:

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 syntaxe est-elle highestStudent_id SERIAL REFERENCES studentscorrecte? parce que j'en ai vu un autre commehighestStudent_id REFERENCES students(student_id))

Quelle serait la bonne façon de créer la clé étrangère dans postgresql s'il vous plaît?

Hamza
la source
4
Oui, la syntaxe est "correcte". Cependant, la colonne FK ne doit pas être définie comme serialelle le devrait integer. serialn'est pas un type de données «réel», c'est un raccourci pour
renseigner
Si le FK fait référence à une clé primaire, aucune colonne n'est nécessaire. Si le FK fait référence à une clé alternative, des colonnes sont nécessaires.
jarlh
1
Votre clé étrangère fait référence à la table "joueurs". Vous ne semblez pas avoir de table nommée «joueurs».
Mike Sherrill 'Cat Recall' le
@Mike Sherrill 'Cat Recall désolé, mon erreur je voulais dire le plus élevéStudent_id integer REFERENCES étudiants
Hamza

Réponses:

251

En supposant ce tableau:

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

Il existe quatre manières différentes de définir une clé étrangère (lorsqu'il s'agit d'une seule colonne PK) et elles conduisent toutes à la même contrainte de clé étrangère:

  1. Inline sans mentionner la colonne cible:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students
    );
    
  2. En ligne avec la mention de la colonne cible:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
    
  3. Hors ligne à l'intérieur du 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. En tant que alter tabledéclaration distincte :

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

Celui que vous préférez est une question de goût. Mais vous devez être cohérent dans vos scripts. Les deux dernières instructions sont la seule option si vous avez des clés étrangères référençant un PK qui se compose de plus d'une colonne - vous ne pouvez pas définir le FK "en ligne" dans ce cas, par exempleforeign key (a,b) references foo (x,y)

Seules les versions 3) et 4) vous donneront la possibilité de définir votre propre nom pour la contrainte FK si vous n'aimez pas les contraintes générées par le système depuis Postgres.


Le serialtype de données n'est pas vraiment un type de données. C'est juste une notation abrégée qui définit une valeur par défaut pour la colonne extraite d'une séquence. Ainsi, toute colonne référençant une colonne définie comme serialdoit être définie à l'aide du type de base approprié integer(ou bigintpour les bigserialcolonnes)

un cheval sans nom
la source
Ce lien ( postgresqltutorial.com/postgresql-foreign-key ) montre une autre façon de faire ce que vous avez dit ne peut être fait qu'avec la commande 'contrainte' en 3 et 4. Aussi, qu'en est-il de mettre FOREIGN KEY avant le FK? Il semble que lorsque nous faisons cela, nous n'avons pas à déclarer le type de variable?
wordsforthewise