Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Curso de PostgreSQL

Curso de PostgreSQL

Oswaldo Rodríguez González

Oswaldo Rodríguez González

Llaves foráneas

15/32
Recursos

Aportes 56

Preguntas 12

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Hay que tener bastante cuidado con el borrado y la actualizacion en cascada, esto podria generar cuellos de botella en el rendimento del aplicativo cuando se modifica la llave y borrar informacion puede ser una opcion devastadora para la integridad de la informacion.

ALTER TABLE public.trayecto
    ADD FOREIGN KEY (id_estacion)
    REFERENCES public.estacion (id) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE
    NOT VALID;
ALTER TABLE public.trayecto
    ADD FOREIGN KEY (id_tren)
    REFERENCES public.tren (id) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE
    NOT VALID;

En la pestania Action le tenemos que decir que hacer a la base de datos entre la tabla origen y la tabla destino cuando ocurra un cambio:

  • NO ACTION: No hacer nada
  • RESTRICT: Decirle a Postgres que no podemos permitir que la tabla cambie algo.
  • CASCADE: Si cambio la tabla de origen, la tabla destino tambien cambia.
  • SET NULL quiere decir que nuestra columna en esa fila va a dejar de tener por ejemplo el ID que tenia asociado un 77 y va a convertirse en NULL. Esto por que la tabla destino recibe un cambio y le decimos aPostgres que lo ponga en nulo.
  • SET DEFAULT: Si hay un cambio en la tabla origen nuestra tabla destino ponga un valor predeterminado. En un ejemplo un id podra quedar NULL.

LLaves Foranes

  • Consistencia
    Estructura
  • Tabla origen
  • Tabla destino
  • Acciones
-- Agregamos llave foranea de id_estacion a la tabla trayecto
ALTER TABLE public.trayecto
    ADD CONSTRAINT trayecto_estacion_fkey FOREIGN KEY (id_estacion)
    REFERENCES public.estacion (id) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE
    NOT VALID;

-- Agregamos llave foranea de id_tren a la tabla trayecto
ALTER TABLE public.trayecto
    ADD CONSTRAINT trayecto_tren_fkey FOREIGN KEY (id_tren)
    REFERENCES public.tren (id) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE
    NOT VALID;

-- Agregamos llave foranea de id_trayecto a la tabla viaje
ALTER TABLE public.viaje
    ADD CONSTRAINT viaje_trayecto_fkey FOREIGN KEY (id_trayecto)
    REFERENCES public.trayecto (id) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE
    NOT VALID;

-- Agregamos llave foranea de id_pasajero a la tabla viaje
ALTER TABLE public.viaje
    ADD CONSTRAINT viaje_pasajero_fkey FOREIGN KEY (id_pasajero)
    REFERENCES public.pasajero (id) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE
    NOT VALID;

-- Para borrar una llave foranea por si tienes algun error
ALTER TABLE public.viaje DROP CONSTRAINT viaje_trayecto_fkey;

Excelente clase, lo uníco que este video debería estar inmediatamente despues de la creacion de tablas porque estuve sufriendo un poco para hacer la relacion de las llaves foreaneas.

Si alguien se adelanto y necesitan hacer una modificacion a sus CONSTRAINT, la solucion es la siguiente

Primero borran el Constraint

ALTER TABLE public.trayecto DROP CONSTRAINT tren_fkey;

Despues lo vuelven a crear con los respectivos cambios

ALTER TABLE public.trayecto
    ADD CONSTRAINT tren_fkey FOREIGN KEY (id_tren)
    REFERENCES public.tren (id) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE;

Ya habia aplicado las FK por mi cuenta al momento de crear las tablas, pero de igual manera aprendi un par de tips que no habia tenido en cuenta.

Ponganlo en x1.25. Sirve mucho 😄

Pestaña Action: Cuando se produce un cambio en un llave primaria esta afectará a su llave foránea, con Action especificamos el resultado que queremos.

Información resumida de esta clase
#EstudiantesDePlatzi

  • Las llaves foreanas son la relación que existe dentro de las tablas, su estructura se compone de tabla de origen, tabla de destino y acciones

  • Por estándar el nombre de la llave foreana va: Tabla de origen, tabla de destino y fkey

  • En la pestaña acción le decimos que debe hacer la base de datos cuando ocurra un cambio

--
-- Creación de la tabla Viaje
--
CREATE TABLE public.viaje
(
    id serial NOT NULL,
    id_pasajero integer,
    id_trayecto integer,
    inicio date,
    fin date,
    CONSTRAINT viaje_pkey PRIMARY KEY (id),
    CONSTRAINT viaje_pasajero_fkey FOREIGN KEY (id_pasajero)
        REFERENCES public.pasajero (id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE
        NOT VALID,
    CONSTRAINT viaje_trayecto_fkey FOREIGN KEY (id_trayecto)
        REFERENCES public.trayecto (id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE
        NOT VALID
)
WITH (
    OIDS = FALSE
);

ALTER TABLE public.viaje
    OWNER to postgres;
COMMENT ON TABLE public.viaje
    IS 'Esta tabla contiene datos  sobre los viajes que pueden hacer los pasajeros ';

COMMENT ON CONSTRAINT viaje_pasajero_fkey ON public.viaje
    IS 'Este campo hace referencia al  ID de la tabla pasajero';
COMMENT ON CONSTRAINT viaje_trayecto_fkey ON public.viaje
    IS 'Este campo hace referencia al  ID de la tabla trayecto';

--
-- Creación de la tabla trayecto
--
CREATE TABLE public.trayecto
(
    id serial NOT NULL,
    id_tren integer,
    id_estacion integer,
    CONSTRAINT trayecto PRIMARY KEY (id_tren),
    CONSTRAINT trayecto_tren_fkey FOREIGN KEY (id_tren)
        REFERENCES public.tren (id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE
        NOT VALID,
    CONSTRAINT trayecto_estacion_fkey FOREIGN KEY (id_estacion)
        REFERENCES public.estacion (id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE
        NOT VALID
)
WITH (
    OIDS = FALSE
);

ALTER TABLE public.trayecto
    OWNER to postgres;
COMMENT ON TABLE public.trayecto
    IS 'Registra los trayectos que pueden hacer los trenes entre estaciones';

COMMENT ON CONSTRAINT trayecto_tren_fkey ON public.trayecto
    IS 'Referencia al  ID de la tabla tren';
COMMENT ON CONSTRAINT trayecto_estacion_fkey ON public.trayecto
    IS 'Referencia al ID de la tabla  estacion';

--Como  agregar constrains manualmente
   ALTER TABLE trayecto ADD CONSTRAINT trayecto_tren_fkey FOREIGN KEY (id_tren)
        REFERENCES public.tren (id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE
        NOT VALID,
    ALTER TABLE trayecto ADD CONSTRAINT trayecto_estacion_fkey FOREIGN KEY (id_estacion)
        REFERENCES public.estacion (id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE
        NOT VALID

No se explico que significa el NOT VALID y ademas el profesor creo algunas llaves con esta condición y otras no. En resumen si una llave foranea incluye esta sentencia no tiene la restricción de que la información de esta columna deba ser una llave foranea.

Para el que le interese saber más acá:

https://blog.dbi-services.com/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql/

Llaves foráneas

Una llave foranea es la manera en que los datos son relacionados entre tablas. La tabla base u origen debe contener obligatoriamente una llave primaria, mientras que la tabla de referenciada o destino debe tener un campo alusivo a la llave primaria de la tabla origen.

Existen diversas opciones para generar la relacion entre las tablas que tienen que ver con la operabilidad y el comportamiento del flujo de información, como el manejo en cascada de acciones de tabla (update y delete), la forma en que se va a construir la llave (validar la integridad de información o no hacerlo al momento de crearla) y demás operaciones de performance.

El objetivo prinicipal de una llave foránea es asegurar la integridad de información y dar sentido al modelo relacional de bases de datos. Su uso es adecuado por temas de normalización, sin embargo, no es suficiente con generar relaciones. Estas deben analizarse con respecto al consumo de información, ya que pueden ser motivo de ralentización de datos y problemas de performance en casos no optimizados (como indexado, por ejemplo).

SQL era un tema que siempre quise aprender desde la universidad y estar en este proceso se siente tan increíble. Excelente la forma en la que Oswaldo explica.

Estructura de las Foreing Keys es = Nombre_Constrains+ Tabla_origen.campo_id_referencia + Tabla_destino.campo_id_referenciado + Acciones.

Yo tuve un error porque en el nombre de la columna id_tren puse un espacio, de la siguiente manera "id_tren ", en pgAdmin el error no era tan explícito, pero no me dejaba añadir la llave foránea, por lo cual lo hice en SQL Shell directamente con los comandos y ahí ya me decía que la columna “id_tren” no existía, porque difería de mi nombre por ese espacio adicional que puse sin darme cuenta.

Si alguien más como yo le aparecía el error de please specify covering index la solución es solo presionar el icono de modificar dos veces y se quita ese error.
https://stackoverflow.com/questions/61441186/postgresql-what-is-meant-by-please-specify-covering-index-name

Vaia, qué interesante clase, esto nunca lo había tomado en cuenta y qué importante es.

Muy buena clase.

El profesor se ha equivocado cuando dice que NO ACTION no permite el eliminado del registro foraneo. Cuando se pone NO ACTION como acción, lo que va a suceder es eso: nada. En caso contrario cuando se pone RESTRICT lo que va a hacer la base de datos es lanzar un error cuando se trate de eliminar el registro foraneo.

excelente clase

Intente muchas veces en la creación de las tablas trayectos y viajes con las llaves foraneas desde PGadmin pero queria asignarle ambas llaves foraneas respectivas de cada tabla y no pude. Mucho mas facil por consola:

CREATE TABLE trayectos(
id serial NOT NULL,
id_estacion integer,
id_tren integer,
PRIMARY KEY(id),
CONSTRAINT trayecto_estacion_fk
 FOREIGN KEY(id_estacion)
  REFERENCES estaciones(id)
  ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT trayecto_tren_fk
FOREIGN KEY(id_tren)
REFERENCES trenes(id)
ON UPDATE CASCADE
ON DELETE CASCADE)
;
CREATE TABLE viajes(
id serial NOT NULL,
id_trayecto integer,
id_pasajero integer,
inicio timestamp,
fin timestamp,
PRIMARY KEY(id),
CONSTRAINT viaje_trayecto_fk
FOREIGN KEY(id_trayecto)
REFERENCES trayectos(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT viaje_pasajero_fk
FOREIGN KEY(id_pasajero)
REFERENCES pasajeros(id)
ON UPDATE CASCADE
ON DELETE CASCADE);

Me frustó esta clase, no puedo entender, no puedo seguir, no me funcionan los comandos.

Creadas mis llaves foraneas para tablas de relaciones… trajectory and travels

¿Es bueno tener la inicial en mayuscula de una tabla?

Al tratar de crear la llave foranea por asql, me sale el siguiente mensaje en la imagen # “ERROR: no existe la relación «trayecto»
SQL state: 42P01”

revisando veo que la table es asi, agradezco de su amable gestión.

La llave foránea tiene una estructura básica. Tabla local, tabla referida y las acciones en caso que haya una modificación en la tabla referida.
Con esta herramienta le decimos a PostgreSQL que relación mantener entre tablas y que hacer cada vez que haya una modificación en la columna de referencia.
Estas modificaciones hacen que la base de datos sea consistente.
Corresponde con nuestro ACID estándar en la parte de consistencia (ACID :https://es.wikipedia.org/wiki/ACID)

![]()

tengo esl siguiente error al crear la llave foranea

Creación de llaves foráneas.

esta clase deberia haberse puesto despues de la creacion de tablas

NOT VALID

Como saber por ejemplo desde que tabla crear la llave foránea a otra, en el ejemplo desde TRAYECTO se crearon las foráneas a ESTACION y TREN, no sería igual hacerlo por ejemplo desde ESTACION a TRAYECTO y TREN a TRAYECTO?

seria mucho mas sencillo hacerlo con querys directas en vez de hacerlo de la manera que lo hace

hacer claves foraneas en postgres

muy buena explicación entendí a la perfección

PgSQL cumple el estándar A.C.I.D: Atomicity-Atomicidad, Consistency-Consistencia, Isolation-Aislamiento, Durability-Durabilidad.

Consistencia: Corresponde al concepto de que los datos tienen una congruencia entre sí tiene que ver la tabla de usuarios, por ejemplo, con la tabla de direcciones.

Opciones de las foreing Keys son: Deferreable (Aplazar validación), Deferred (Apenas se crea se válida), Match Type (SIMPLE=VALOR A VALOR OR FULL=COMPLEJA) , Validated (Iniciamos las tablas con la validación), Auto FK Index (No es un indice de la tabla)

En la pestaña Action de los contraints es una pestaña en donde indicamos la acción a tomar por el motor de la base de dato cuando ocurre una actualización del registro de la tupla referenciada por este campo

En la pestaña Definition de los constraints existen Características (Definitions) especiales al foreing Keys permite hacer una llave foránea sea validada al instante o después.

Muy interesante 😮

Estoy haciendo otra DB diferente y resulta que al insertar datos y omitiendo el campo foraneo debería arrojar error pero está dejando guardar los datos, ya revisé y la relacion esta bien apuntada. A alguien le ha pasado?

Muy completa esta expliación!

Super Excelente esa explicación, muy buena pa que.

excelente explicacion

Importante hacer bien las relaciones,para no tener problemas después

Crear llave Foránea con pdAdmin: Properties / Constraints / Foreign Key

Llaves Foráneas y estructura

Creación de Foreign Key con Queries a través de la pestaña Tools / Query Tool

Si a alguno le sale el mensaje “please specify covering index name” las posibles soluciones serian.

  1. Colocar auto fk index: yes y su covering index.
  2. introduce la modificación usando el tool de SQL.

Nota: Es mejor la segunda opción.

El caso de las cascadas me parece un dato muy interesante, lo voy a comenzar a manejar.

ALTER TABLE public.viaje
ADD CONSTRAINT viaje_estacion_fkey FOREIGN KEY (id_estacion)
REFERENCES public.estacion (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
NOT VALID;

ALTER TABLE public.viaje
ADD CONSTRAINT viaje_pasajero_fkey FOREIGN KEY (id_pasajero)
REFERENCES public.pasajero (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
NOT VALID;

ALTER TABLE public.trayecto
ADD CONSTRAINT trayecto_tren_fkey FOREIGN KEY (id_tren)
REFERENCES public.estacion (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
NOT VALID;

ALTER TABLE public.trayecto
ADD CONSTRAINT trayecto_estacion_fkey FOREIGN KEY (id_estacion)
REFERENCES public.estacion (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
NOT VALID;

Aqui viene mas información sobre las diferentes opciones
localhost/help/help/table_dialog.html

Creo que estoy amando cada vez mas la terminal xD.

Es importante entender para que vamos a hacer una relacion entre tablas, si es necesaria o no, la velocidad de nuestra base de datos dependera de si es que configuramos bien o no las relaciones entre tablas. Recuerden que muchas veces en nuetras bases de datos velocidad significa dinero 🤑