sintaxis de clave externa de postgresql

122

Tengo 2 tablas como verá en mi código posgresql a continuación. La primera tabla estudiantes tiene 2 columnas, una para nombre_estudiante y la otra id_estudiante, que es la clave principal. En mi segunda tabla llamada tests, tiene 4 columnas, una para subject_id, una para subject_name, luego otra para un estudiante con la puntuación más alta en una materia que es la más alta Student_id. Estoy tratando de hacer que más altoStudent_id se refiera a student_id en mi tabla de estudiantes. Este es el código que tengo a continuación, no estoy seguro de si la sintaxis es correcta:

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

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

¿es highestStudent_id SERIAL REFERENCES studentscorrecta la sintaxis ? porque he visto otro comohighestStudent_id REFERENCES students(student_id))

¿Cuál sería la forma correcta de crear la clave externa en postgresql, por favor?

Hamza
fuente
4
Sí, la sintaxis es "correcta". Sin embargo, la columna FK no debería definirse como serialdebería definirse como integer. serialno es un tipo de datos "real", es una forma abreviada de
rellenar
Si FK hace referencia a una clave primaria, no se necesitan columnas. Si FK hace referencia a una clave alternativa, se necesitan columnas.
jarlh
1
Su clave externa hace referencia a los "jugadores" de la mesa. No parece tener una mesa llamada "jugadores".
Mike Sherrill 'Cat Recall'
@Mike Sherrill 'Cat Recall lo siento, mi error quise decir más altoStudent_id integer REFERENCIAS estudiantes
Hamza

Respuestas:

250

Asumiendo esta tabla:

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

Hay cuatro formas diferentes de definir una clave externa (cuando se trata de un PK de una sola columna) y todas conducen a la misma restricción de clave externa:

  1. Inline sin mencionar la columna de destino:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students
    );
  2. En línea con la mención de la columna de destino:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
  3. Fuera de línea dentro de 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. Como alter tabledeclaración separada :

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

Cuál prefieres es cuestión de gustos. Pero debes ser coherente con tus guiones. Las dos últimas declaraciones son la única opción si tiene claves externas que hacen referencia a un PK que consta de más de una columna; no puede definir el FK "en línea" en ese caso, por ejemploforeign key (a,b) references foo (x,y)

Solo la versión 3) y 4) le dará la capacidad de definir su propio nombre para la restricción FK si no le gustan los generados por el sistema desde Postgres.


El serialtipo de datos no es realmente un tipo de datos. Es solo una notación abreviada que define un valor predeterminado para la columna tomada de una secuencia. Por lo tanto, cualquier columna que haga referencia a una columna definida como serialdebe definirse utilizando el tipo de base apropiado integer(o bigintpara bigserialcolumnas)

un caballo sin nombre
fuente
Este enlace ( postgresqltutorial.com/postgresql-foreign-key ) muestra otra forma de hacer lo que dijo que solo se puede hacer con el comando 'constricción' en 3 y 4. Además, ¿qué hay de poner FOREIGN KEY antes de FK? Parece que cuando hacemos eso, ¿no tenemos que declarar el tipo de variable?
wordsforthewise