Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] relación a una tabla u a otra tabla

From: Victor Hugo Roumieu <vhr273(at)gmail(dot)com>
To: Jaime Casanova <jaime(at)2ndquadrant(dot)com>
Cc: "Guillermo E(dot) Villanueva" <guillermovil(at)gmail(dot)com>, Martín Marqués <martin(at)2ndquadrant(dot)com>, Laura Martinelli <lmartinelli(at)unlu(dot)edu(dot)ar>, Luis Ramon Sanchez Rico <sabrewolf76(at)gmail(dot)com>, POSTGRES <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] relación a una tabla u a otra tabla
Date: 2014-05-06 05:05:26
Message-ID: CAPrQUT4VrRDG6twSq5keoJGWP79YbmSR=5gLS07h+QkUzUiduA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Estimados, pido disculpas por sumarme a este hilo, es posible que nos
estemos llendo de tema. Pero lo creo interesante

La primera respuesta de Jaime del 14 de abril, fue impecable. Los viejitos
como yo, lo llamamos exclucion mutua, luego un par de mensajes mas tarde
Alvaro mejora haciendo mas corto la constrain.

Ahora para ver otras opciones de resolver el problema, dependiendo del
entorno de cada coso en particular, es posible que con herencia se tengan
ventajas. (muy dificil que pase... pero pasa) Obvio que es mejor o que peor
siempre es para discutir.

Les paso un scripts con dos modos de resolver el problema con herencia, de
los cuales yo uso el segundo ( obvio con mas trabajo, pues en este ejemplo
esta resumido)

----------
--- Modo 1
--- Usando herencia de postgres, pero en mi ignorancia sobre el tema, lo
debo complementar con un trigger, pues en herencia no se propaga de la
clase padre a las hijas
--- las primary key y si inserto en la hija en realidad no inserta en el
padre
--- de modo que no es una solucion valida, yo en realidad siempre uso el
modo 2 en estos casos, pero el modo 1 es mas didactico
---------

drop schema univ cascade;
create schema univ;

CREATE DOMAIN univ.tipos_catedras
AS integer
DEFAULT 1
CONSTRAINT tipos_catedras_check CHECK (VALUE = ANY (ARRAY[0, 1]));
COMMENT ON DOMAIN univ.tipos_catedras
IS '1= Materias
0= Talleres';

create table univ.catedras
(
id serial not null primary key,
tipo_catedra univ.tipos_catedras,
nombre text
);

create table univ.materias
(
profesor text,
etc text
) INHERITS (univ.catedras);

create table univ.talleres
(
jefe_trabajo_practico text,
etc text
) INHERITS (univ.catedras);

CREATE OR REPLACE FUNCTION univ.f1_fnc()
RETURNS trigger AS
$BODY$
DECLARE
v_c integer;

BEGIN
IF (TG_OP = 'INSERT') THEN
if TG_TABLE_NAME = 'materias' then
v_c := 1;
else
v_c := 0;
end if;
insert into univ.catedras (id,tipo_catedra,nombre) values (
NEW.id,v_c,NEW.nombre);
RETURN NEW;
ELSE
RAISE WARNING 'se llamo mal: %, at %',TG_OP,now();
RETURN NULL;
END IF;

END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;

CREATE TRIGGER materias_trg
BEFORE INSERT
ON univ.materias
FOR EACH ROW
EXECUTE PROCEDURE univ.f1_fnc();

CREATE TRIGGER talleres_trg
BEFORE INSERT
ON univ.talleres
FOR EACH ROW
EXECUTE PROCEDURE univ.f1_fnc();

insert into univ.materias ( tipo_catedra, nombre, profesor, etc ) values
(1,'tejido','prf1','etc');
insert into univ.materias ( tipo_catedra, nombre, profesor, etc ) values
(1,'lavar ropa','prf2','etc2');

insert into univ.talleres ( tipo_catedra, nombre, jefe_trabajo_practico,
etc ) values (0,'modo correcto de apretar tuercas','jefe1','etc8');
insert into univ.talleres ( tipo_catedra, nombre, jefe_trabajo_practico,
etc ) values (0,'modo correcto de aflojar tuercas','cocacola','etc9');

insert into univ.materias ( tipo_catedra, nombre, profesor, etc ) values
(1,'otra cosa','prf2','etc32');
insert into univ.talleres ( tipo_catedra, nombre, jefe_trabajo_practico,
etc ) values (0,'modo correcto de clavar clavitos','jefe2','etc6');

select * from univ.catedras order by id;
select * from univ.materias;
select * from univ.talleres;

drop table univ.inscripciones;

create table univ.inscripciones
( id serial not null primary key,
alumno text,
fecha timestamp,
loquefuera text,
catedra integer not null references univ.catedras(id)
);

insert into univ.inscripciones (alumno,catedra) values ('Jose',1);
insert into univ.inscripciones (alumno,catedra) values ('Jose',2);
insert into univ.inscripciones (alumno,catedra) values ('Jose',3);
insert into univ.inscripciones (alumno,catedra) values ('Jose',4);
insert into univ.inscripciones (alumno,catedra) values ('Jose',5);

select * from univ.catedras where id= 1

----------
--- Modo 2
--- lo mismo pero sin herencia o con una simulacion de herencia
---------

drop schema univ1 cascade;
create schema univ1;

CREATE DOMAIN univ1.tipos_catedras
AS integer
DEFAULT 1
CONSTRAINT tipos_catedras_check CHECK (VALUE = ANY (ARRAY[0, 1]));
COMMENT ON DOMAIN univ1.tipos_catedras
IS '1= Materias
0= Talleres';

create table univ1.catedras
(
id serial not null primary key,
tipo_catedra univ1.tipos_catedras
);

create table univ1.materias
(
id integer not null primary key references univ1.catedras(id),
nombre text,
profesor text,
etc text
);

create table univ1.talleres
(
id integer not null primary key references univ1.catedras(id),
nombre text,
jefe_trabajo_practico text,
etc text
);

CREATE OR REPLACE FUNCTION univ1.f1_fnc()
RETURNS trigger AS
$BODY$
DECLARE
v_c integer;
BEGIN
IF (TG_OP = 'INSERT') THEN
if NEW.id is null then
NEW.id := nextval('univ1.catedras_id_seq');
end if;
if TG_TABLE_NAME = 'materias' then
v_c := 1;
else
v_c := 0;
end if;
insert into univ1.catedras (id,tipo_catedra) values ( NEW.id,v_c);
RETURN NEW;
ELSE
RAISE WARNING 'se llamo mal: %, at %',TG_OP,now();
RETURN NULL;
END IF;

END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;

CREATE TRIGGER materias_trg
BEFORE INSERT
ON univ1.materias
FOR EACH ROW
EXECUTE PROCEDURE univ1.f1_fnc();

CREATE TRIGGER talleres_trg
BEFORE INSERT
ON univ1.talleres
FOR EACH ROW
EXECUTE PROCEDURE univ1.f1_fnc();

insert into univ1.materias ( nombre, profesor, etc ) values
('tejido','prf1','etc');
insert into univ1.materias ( nombre, profesor, etc ) values ('lavar
ropa','prf2','etc2');

insert into univ1.talleres ( nombre, jefe_trabajo_practico, etc ) values
('modo correcto de apretar tuercas','jefe1','etc8');
insert into univ1.talleres ( nombre, jefe_trabajo_practico, etc ) values
('modo correcto de aflojar tuercas','cocacola','etc9');

insert into univ1.materias ( nombre, profesor, etc ) values ('otra
cosa','prf2','etc32');
insert into univ1.talleres ( nombre, jefe_trabajo_practico, etc ) values
('modo correcto de clavar clavitos','jefe2','etc6');

select * from univ1.catedras order by id;
select * from univ1.materias;
select * from univ1.talleres;

drop table univ1.inscripciones;

create table univ1.inscripciones
( id serial not null primary key,
alumno text,
fecha timestamp,
loquefuera text,
catedra integer not null references univ1.catedras(id)
);

insert into univ1.inscripciones (alumno,catedra) values ('Jose',1);
insert into univ1.inscripciones (alumno,catedra) values ('Jose',2);
insert into univ1.inscripciones (alumno,catedra) values ('Jose',3);
insert into univ1.inscripciones (alumno,catedra) values ('Jose',4);
insert into univ1.inscripciones (alumno,catedra) values ('Jose',5);

select * from univ1.inscripciones

select * from univ1.catedras where id= 1

Desde ya muchas gracias por vuestra tolerancia a un mail tan largo, y
espero que le fuera de utilidad a alguna persona.
Saludos
VHR

El 5 de mayo de 2014, 18:30, Jaime Casanova <jaime(at)2ndquadrant(dot)com>escribió:

> 2014-05-05 13:35 GMT-05:00 Guillermo E. Villanueva <guillermovil(at)gmail(dot)com
> >:
>
> Si si, eso es lo que dijo Alvaro y no lo discuto. Solo digo que no es
>> bueno que ya por diseño uno de los dos campos va a ser NULL en todas las
>> filas.
>>
>>
>
> no por diseño, es la implementación de un diseño en el que se usa la misma
> tabla para almacenar ambos datos.
> la otra implementación posible es la que mencione, un campo tipo y usar el
> mismo campo con un constraint trigger para RI
>
> cual es mejor? probablemente la que incluye dos campos. un campo null
> ocupa un solo bit (lo que se traduce en al menos 1 byte pero si ya tienes
> campos en null no usas nada adicional) y como ventaja adicional no debes
> inventar la rueda tratando de hacer un constraint trigger que simule el FK
>
> mientras que en la otra opción, son dos campos not null (es decir que
> usamos al menos 5 bytes) mas el constraint trigger
>
> ahora, la estructura física de la tabla es solo la forma en que
> implementas el diseño lógico y no deberías alterar el diseño lógico
> pensando solo en la estructura física sino al reves
>
> --
> Jaime Casanova www.2ndQuadrant.com
> Professional PostgreSQL: Soporte 24x7 y capacitación
> Phone: +593 4 5107566 Cell: +593 987171157
>

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Marcos Michel Martínez Pérez 2014-05-06 14:07:51 Re: creando backup con barman
Previous Message Alvaro Herrera 2014-05-06 00:27:03 Re: Como sé si mi hardware ya no me permite ejecutar más rapidamente una setencia SELECT en PostgreSQL