Estoy luchando con claves externas en mi base de datos, posiblemente tiene algo que ver con la herencia?
Así que aquí es la configuración básica:No existe la clave externa PostgreSQL, ¿problema de herencia?
-- table address
CREATE TABLE address
(
pk_address serial NOT NULL,
fk_gadmid_0 integer NOT NULL, -- this table already exists, no problem here
street character varying(100),
zip character varying(10),
city character varying(50),
public boolean,
CONSTRAINT address_primarykey PRIMARY KEY (pk_address),
CONSTRAINT gadmid_0_primarykey FOREIGN KEY (fk_gadmid_0)
REFERENCES adm0 (gadmid_0) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE address OWNER TO postgres;
-- table stakeholder (parent)
CREATE TABLE stakeholder
(
pk_stakeholder integer DEFAULT nextval('common_stakeholder_seq') NOT NULL,
fk_stakeholder_type integer NOT NULL, -- this table also exists, no problem here
name character varying(255) NOT NULL,
CONSTRAINT stakeholder_primarykey PRIMARY KEY (pk_stakeholder),
CONSTRAINT stakeholder_fk_stakeholder_type FOREIGN KEY (fk_stakeholder_type)
REFERENCES stakeholder_type (pk_stakeholder_type) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE stakeholder OWNER TO postgres;
-- table individual (child of stakeholder)
CREATE TABLE individual
(
firstname character varying(50),
fk_title integer, -- this table also exists, no problem here
email1 character varying (100),
email2 character varying (100),
phone1 character varying (50),
phone2 character varying (50),
CONSTRAINT individual_primarykey PRIMARY KEY (pk_stakeholder),
CONSTRAINT title_foreignkey FOREIGN KEY (fk_title)
REFERENCES title (pk_title) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
) INHERITS (stakeholder)
WITH (
OIDS=FALSE
);
ALTER TABLE individual OWNER TO postgres;
-- link between stakeholder and address
CREATE TABLE l_stakeholder_address
(
pk_l_stakeholder_address serial NOT NULL,
fk_stakeholder integer NOT NULL REFERENCES stakeholder,
fk_address integer NOT NULL REFERENCES address,
CONSTRAINT l_stakeholder_address_primarykey PRIMARY KEY (pk_l_stakeholder_address),
CONSTRAINT l_stakeholder_address_fk_stakeholder FOREIGN KEY (fk_stakeholder)
REFERENCES stakeholder (pk_stakeholder) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION,
CONSTRAINT l_stakeholder_address_fk_address FOREIGN KEY (fk_address)
REFERENCES address (pk_address) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE l_stakeholder_address OWNER TO postgres;
Hasta el momento, no hay problema. Luego he intentado añadir algunos valores:
INSERT INTO individual (pk_stakeholder, fk_stakeholder_type, name, firstname, fk_title, email1, email2, phone1, phone2)
VALUES (1, 8, 'Lastname', 'Firstname', 1, '[email protected]', '', '', '');
INSERT INTO address (pk_address, fk_gadmid_0, street, zip, city, public)
VALUES (1, 126, 'Address', '', 'City', FALSE);
INSERT INTO l_stakeholder_address (pk_l_stakeholder_address, fk_stakeholder, fk_address)
VALUES (DEFAULT, 1, 1);
Y finalmente me acaban de tener un error (estado de SQL 23503) diciendo que la clave (fk_stakeholder) = (1) no está vigente en la tabla "partes interesadas".
Los 2 primeros insertos están muy bien, puedo ver en las bases de datos:
stakeholder:
pk_stakeholder | ...
----------------------
1 | ...
address:
pk_address | ...
--------------------
1 | ...
¿Qué estoy haciendo mal? Debo admitir que soy bastante nuevo en PostgreSQL (usando 8.4), pero ni siquiera estoy seguro de si eso es un problema de PG, tal vez me faltan algunos entendimientos básicos de diseño de bases de datos ...
De cualquier manera, por ahora, probé casi todo lo que podía pensar, también intenté diferir el FK como en el PostgreSQL : Transaction and foreign key problem, pero de alguna manera eso tampoco funciona.
Muchas gracias por su respuesta, logré resolver mi problema de esa manera. Sin embargo, en lugar de 'individual_pks', prefiero 'stakeholder_pk', ya que el stakeholder es la tabla padre. Entonces 'stakeholder_pk' recoge todas las claves principales de 'stakeholder' y sus hijos. ¡Gracias! – Lukas