Em Qui, 2015-02-05 às 09:59 -0200, Matheus de Oliveira escreveu: > > > 2015-02-05 6:39 GMT-02:00 Flavio Henrique Araque Gurgel > <[email protected]>: > > Agora, com sua explicação, pensemos assim, veja se entendi > direito > > A - Itens de nota > B - Cabeçalho da nota > C - Orçamentos > > O que entendo é que você está tentando usar o máximo possível > de chaves naturais, logo, B e C usarão a mesma chave, ou seja, > o número de um orçamento no fim será também o número da nota > (o que me parece bizarro ao pensar mas talvez seu sistema seja > particularmente diferente por alguma razão do seu modelo de > negócio). > > Logo: > A (coluna_chave) -> B(ID) > A (coluna_chave) -> C(ID) > > Isso parece funcionar no modelo. No mundo real é que parece > estranho. > > > > > hm... Agora me confundi, não sei entendi bem como isso funcionaria. > > Vamos imaginar o seguinte, temos uma nota com B.ID=3 e um orçamento > com C.ID=4, na tabela A você teria então diversos registros com A.ID=3 > e vários com A.ID=4. O problema é, se você tem duas FKs da coluna A.ID > para B.ID e C.ID, quando A.ID for 3 a FK para C.ID vai ser violada, e > quando A.ID=4 a FK para B.ID é que será violada. Exemplo: > > postgres=# CREATE TEMP TABLE b(id integer PRIMARY KEY); > CREATE TABLE > > postgres=# INSERT INTO b VALUES(3); > INSERT 0 1 > > postgres=# CREATE TEMP TABLE c(id integer PRIMARY KEY); > CREATE TABLE > > postgres=# INSERT INTO c VALUES(4); > INSERT 0 1 > > postgres=# CREATE TEMP TABLE a(id integer, FOREIGN KEY (id) > REFERENCES b(id), FOREIGN KEY (id) REFERENCES c(id)); > CREATE TABLE > > postgres=# INSERT INTO a VALUES(3); > ERROR: 23503: insert or update on table "a" violates foreign key > constraint "a_id_fkey1" > DETAIL: Key (id)=(3) is not present in table "c". > SCHEMA NAME: pg_temp_2 > TABLE NAME: a > CONSTRAINT NAME: a_id_fkey1 > LOCATION: ri_ReportViolation, ri_triggers.c:3232 > > postgres=# INSERT INTO a VALUES(4); > ERROR: 23503: insert or update on table "a" violates foreign key > constraint "a_id_fkey" > DETAIL: Key (id)=(4) is not present in table "b". > SCHEMA NAME: pg_temp_2 > TABLE NAME: a > CONSTRAINT NAME: a_id_fkey > LOCATION: ri_ReportViolation, ri_triggers.c:3232 > > > Estou entendendo que B e C são disjuntas, assim sendo eu diria para > ter uma outra tabela, vamos chamá-la de D (talvez "Pedidos" no > exemplo?), que terá as informações em comum de ambas as tabelas B e C > (por exemplo, data de lançamento, cliente, etc.) e ambas tabelas B e C > tem FKs para D, da mesma forma que A tem FK para D. Deve ser então > garantido de outra forma que o ID em A esteja correspondendo > corretamente em B para nota ou C para orçamentos, nesse caso podemos > adicionar mais duas colunas em A uma com FK para cada um e garantir > com trigger que elas tenham o mesmo ID que a coluna referenciando D ou > que sejam NULL. Nesse caso as tabelas do meu exemplo ficariam como > (não testei): > > > CREATE TEMP TABLE d(id integer PRIMARY KEY); > CREATE TEMP TABLE c(id integer PRIMARY KEY REFERENCES d(id)); > CREATE TEMP TABLE b(id integer PRIMARY KEY REFERENCES d(id)); > CREATE TEMP TABLE a( > id integer PRIMARY KEY REFERENCES d(id), > b_id integer REFERENCES b(id), > c_id integer REFERENCES c(id), > CHECK(b_id IS NULL OR b_id = id), > CHECK(c_id IS NULL OR c_id = id), > CHECK(b_id IS NULL <> c_id IS NULL) > ); > > > > Por favor, me corrijam se eu estiver falando alguma besteira... ;-) > >
Bem, segue um DER para tentar explicar. Como pode ser visto na imagem, o campo 'nota_ou_orca' da tabela 'ITENS' é a chave primária da tabela e também faz parte de duas chaves estrangeiras, uma que aponta para 'NOTA' outra que aponta para 'ORCAMENTO'. Tenho minhas dúvidas se daria certo. Tipo, na hora de inserir um registro em 'ITENS' qual tabela seria usada para validar a chave estrangeira, NOTA ou ORCAMENTO? Digamos que na tabela NOTAS exista registros mas que a tabela ORCAMENTO esteja vazia. A chave estrangeira que aponta para ORCAMENTO não lançaria um erro?
_______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
