Re: OT: mejores practicas

From: "Miguel Beltran R(dot)" <yourpadre(at)gmail(dot)com>
To: Jaime Casanova <jcasanov(at)systemguards(dot)com(dot)ec>
Cc: Foro PostgreSQL <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: OT: mejores practicas
Date: 2009-03-22 04:13:49
Message-ID: b623c7e40903212113sa20d428y7c6e158db935a657@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Primero gracias a todos por contestar

El 20 de marzo de 2009 9:31, Jaime Casanova
<jcasanov(at)systemguards(dot)com(dot)ec>escribió:

> 2009/3/19 Miguel Beltran R. <yourpadre(at)gmail(dot)com>:
> > Platicando con un amigo sobre como es mejor diseñar una base de datos
> > tenemos un punto de desacuerdo.
> >
> > Yo digo que siguiendo la normalización en ocaciones puede ser un problema
> > creo (ó es un mal diseño mio tal vez).
> >
>
> esto no parece muy normalizado que digamos...
>
> > Por ejemplo siguiendo la normalización (la estructura es solo para dar
> una
> > idea):
> > tablaA {
> > id serial;
> > proyectoA integer PRIMARY KEY;
> > proyectoA_nombre text;
> > anio integer;
> > }
> >
>
> para que el "id serial"? todas las tablas tienen uno y me parece que
> no sirve a ningun proposito util...

Su mayor proposito es como punto de referencia de saber en que momento se
inserto el dato, para detectar posibles errores de captura. como meter el
proyectoA 99 y si despues reviso darme cuenta que lo metieron despues del
65. y antes del 70. (no siempre nos tocan proyectos consecutivos 11,12,13)

>
>
> > tablaB {
> > id serial;
> > proyectoA integer reference tablaA (proyectoA)
> > proyectoB integer PRIMARY KEY
> > fecha date;
> > fondo varchar(10);
> > cuenta varchar(10);
> > }
> >
>
> si tabla B depende directamente de tabla entonces proyectoA deberia
> formar parte del PK, por ejemplo si tabla B almacena algun tipo de
> detalle (como en el caso de la factura y el detalle de la factura)
> pero sin saber que tipo de informacion se va a almacenar solo son
> conjeturas

TablaB si depende directamente de tablaA. Por lo que se (porque no se
supieron decir los que me pidieron el programa) es que nunca se repite
proyectoB

>
>
> > tablaC {
> > id serial;
> > anio integer; --es el mismo que en tablaA
> > proyetoC integer; --es un consecutivo que empieza
> > --en 1 cada año, no se debe repetir
> > --por eso se combina con anio.
> > proyectoB integer REFERENCE tablaB (proyectoB);
> > }PRIMARY KEY (anio, proyectoC)
> >
>
> si el anio es el mismo que en tabla A no deberia estar aqui, mas bien
> aqui deberia estar el codigo del registro de tablaA lo que me hace que
> pensar que mi suposicion de que proyectoA deberia formar parte del PK
> de tablaB es correcta

Es el mismo, pero esta el anio para no tener que buscar el dato en la
tablaA.

>
>
> > tablaD {
> > id serial;
> > tablaC_id integer REFERENCE tablaC (id)
> > tipo char(1);
> > folio integer;
> > }PRIMARY KEY (tipo, folio)
> >
> >
> > El problema que le digo a mi amigo, es que si necesito unos datos de
> tablaD
> > filtrada por anio y proyectoA tengo que hacer muchos INNER JOIN -((tablaA
> > inner JOIN tablaB) inner join tablaC) inner join tablaD-, y yo se que me
> van
> > a pedir muchos reportes con esas caracteristicas. Y como estas los costos
> de
> > almacenaje no representa mucho el gasto espacio de disco duro y si mas
> > rapides si guardo esos 2 campos (ejercicio y proyectoA) en la tablaD.
> >
>
> haz los cambios que te digo y me cuentas...

Hare los cambios y te cuento despues,

>
>
> > ¿quién tiene rázon? ¿cómo sería lo mas rapido/mejor.?
> >
>
> lo mas rapido no siempre es lo mejor y viceversa... mejor es hacerlo
> primero bien y luego preocuparse de que responda rapido... despues de
> todo, "la optimizacion prematura es la raiz de todos los males" (no
> recuerdo quien lo dijo)...
>
Una ultima duda con la rapidez, igual y por eso estoy mal con mis diseños.
Si hago una vista de tablaC que jale el dato de tablaA para tomar el anio,
cuanta carga se para la base. claro que usario indices.

Mejor muestro como estan realmente las tablas importantes.
Ahorita el programa se usa en solo una oficina, pero lo quiero hacer
pensando en que se pueda usar en varias oficinas. que es el campo ures.
ejercicio es el año.

CREATE TABLE proyecto
(
id serial NOT NULL,
proyecto_nombre character(120) NOT NULL,
monto numeric(12,2) NOT NULL DEFAULT 0,
usado numeric(12,2) NOT NULL DEFAULT 0,
inicio date NOT NULL,
fin date NOT NULL,
ejercicio integer NOT NULL,
proyecto character varying(10) NOT NULL,
ures character varying(10) NOT NULL,
programa character varying(10) NOT NULL,
eje character varying(10) NOT NULL,
tipo_proyecto character varying(10) NOT NULL,
justificacion text NOT NULL,
objetivo_general text NOT NULL,
objetivo character varying(10),
fondo_1101 numeric(12,2) NOT NULL DEFAULT 0,
fondo_1102 numeric(12,2) NOT NULL DEFAULT 0,
CONSTRAINT pk_proyecto PRIMARY KEY (proyecto),
CONSTRAINT fk_proyecto_eje FOREIGN KEY (eje)
REFERENCES eje (eje) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_proyecto_ejercicio FOREIGN KEY (ejercicio)
REFERENCES ejercicio (ejercicio) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_proyecto_objetivo FOREIGN KEY (objetivo)
REFERENCES objetivo (objetivo) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_proyecto_programa FOREIGN KEY (programa)
REFERENCES programa (programa) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_proyecto_tipoproyecto FOREIGN KEY (tipo_proyecto)
REFERENCES tipo_proyecto (tipo_proyecto) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_proyecto_ures FOREIGN KEY (ures)
REFERENCES ures (ures) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)

CREATE TABLE actividad
(
id serial NOT NULL,
actividad character varying(10) NOT NULL,
actividad_nombre text NOT NULL,
inicio date NOT NULL,
fin date NOT NULL,
monto numeric(12,2) NOT NULL,
reservado numeric(12,2) NOT NULL DEFAULT 0,
proyecto character varying(10) NOT NULL,
meta character varying(10) NOT NULL,
usado numeric(12,2) NOT NULL DEFAULT 0,
CONSTRAINT pk_actividad PRIMARY KEY (actividad),
CONSTRAINT fk_actividad_meta FOREIGN KEY (meta)
REFERENCES meta (meta) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_actividad_proyecto FOREIGN KEY (proyecto)
REFERENCES proyecto (proyecto) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT ck_actividad_reservado CHECK (reservado <= monto),
CONSTRAINT ck_actividad_usado CHECK (usado <= reservado)
)

CREATE TABLE material
(
id serial NOT NULL,
captura time without time zone NOT NULL DEFAULT now(),
material character varying(10) NOT NULL,
material_nombre character varying(200) NOT NULL,
cuenta character varying(10) NOT NULL,
fondo character varying(10) NOT NULL,
monto numeric(12,2) NOT NULL, -- cuanto se puede usar en esta cuenta de
materia
usado numeric(12,2) NOT NULL DEFAULT 0, -- cuanto se a usado de lo
recibido
actividad character varying(10) NOT NULL,
recibido numeric(12,2) NOT NULL DEFAULT 0, -- de las quincenas reservadas,
cuanto dinero se a recibido realmente
reservado numeric(12,2) NOT NULL DEFAULT 0, -- del total de monto cuanto
se a reservado en quincenas
CONSTRAINT pk_material PRIMARY KEY (material),
CONSTRAINT fk_material_actividad FOREIGN KEY (actividad)
REFERENCES actividad (actividad) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_material_cuenta FOREIGN KEY (cuenta)
REFERENCES cuenta (cuenta) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_material_fondo FOREIGN KEY (fondo)
REFERENCES fondo (fondo) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT ck_material_recibido CHECK (recibido <= reservado),
CONSTRAINT ck_material_reservado CHECK (reservado <= monto),
CONSTRAINT ck_material_usado CHECK (usado <= recibido)
)

CREATE TABLE vale
(
id serial NOT NULL,
captura time with time zone NOT NULL DEFAULT now(),
ejercicio integer NOT NULL,
fecha date NOT NULL,
vale integer NOT NULL,
centro character varying(10) NOT NULL,
ures character varying(10) NOT NULL,
proyecto character varying(10) NOT NULL,
concepto text NOT NULL,
linea integer NOT NULL,
fondo character varying(10) NOT NULL,
xprograma character varying(5) NOT NULL DEFAULT 7.1,
xsubprograma character varying(5) NOT NULL DEFAULT 4.1,
cuenta character varying(10) NOT NULL,
material character varying(10) NOT NULL,
importe numeric(12,2) NOT NULL,
conletra character varying(200) NOT NULL,
responsable character varying(200) NOT NULL,
favor character varying(250) NOT NULL,
condicion integer NOT NULL DEFAULT 1, -- 0: Cancelado...
CONSTRAINT pk_vale PRIMARY KEY (ejercicio, vale),
CONSTRAINT fk_vale_centro FOREIGN KEY (centro)
REFERENCES centro (centro) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_vale_proyecto FOREIGN KEY (proyecto)
REFERENCES proyecto (proyecto) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT uq_vale_id UNIQUE (id),
CONSTRAINT ck_vale_concepto_trim CHECK (btrim(concepto) <> ''::text),
CONSTRAINT ck_vale_condicion CHECK (condicion >= 0 AND condicion <= 9),
CONSTRAINT ck_vale_conletra_trim CHECK (btrim(conletra::text) <>
''::text),
CONSTRAINT ck_vale_favor_trim CHECK (btrim(favor::text) <> ''::text),
CONSTRAINT ck_vale_responsable_trim CHECK (btrim(responsable::text) <>
''::text)
)

CREATE TABLE transaccion
(
id serial NOT NULL,
captura timestamp(3) without time zone NOT NULL DEFAULT now(),
modificado timestamp(3) without time zone NOT NULL DEFAULT now(),
tipo character(1) NOT NULL,
folio integer NOT NULL,
fecha date NOT NULL,
conletra character varying(254) NOT NULL,
importe numeric(12,2) NOT NULL,
favor character varying(254) NOT NULL,
observacion text NOT NULL,
concepto character varying(200) NOT NULL,
vale_id integer NOT NULL,
referencia1 character varying(40) NOT NULL DEFAULT ''::character varying,
referencia2 character varying(40) NOT NULL DEFAULT ''::character varying,
condicion integer NOT NULL DEFAULT 1, -- 0: Cancelado...
CONSTRAINT pk_che_tra PRIMARY KEY (tipo, folio),
CONSTRAINT fk_che_tra_vale FOREIGN KEY (vale_id)
REFERENCES vale (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION,
CONSTRAINT uq_transaccion_id UNIQUE (id),
CONSTRAINT ck_che_tra_condicion CHECK (condicion = 1 OR condicion = 0),
CONSTRAINT ck_che_tra_tipo CHECK (tipo = 'C'::bpchar OR tipo =
'T'::bpchar)
)

Nota. Tengo algunos funciones que cuando se cambia un monto en vale,
actualiza material y este a su vez actualiza actividad y este proyecto. Por
ejemplo en la tabla proyecto tengo fondo_1101 y fondo_1102 que es la suma de
lo que se genera en vale, para no tener que hacer un SUM cada vez que
necesite el dato. La idea la tome del manual de posgtresql donde explican
las funciones.

Gracia a todos otra vez.

>
>
> --
> Atentamente,
> Jaime Casanova
> Soporte y capacitación de PostgreSQL
> Asesoría y desarrollo de sistemas
> Guayaquil - Ecuador
> Cel. +59387171157
>

--
________________________________________
Lo bueno de vivir un dia mas
es saber que nos queda un dia menos de vida

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Alvaro Herrera 2009-03-23 00:00:27 Re: OT: mejores practicas
Previous Message Armando 2009-03-21 22:29:33 Identificar la posicion de un termino en el parser/planner