Problemas de relacionamento

13 respostas
_fs

Oi pessoal, boa tarde.
A dúvida é sobre … SQL :mrgreen:

O problema: representar um relacionamento recursivo sem limites de nível, filhos ou pais.

Portanto, qual a maneira

  • mais rápida
  • mais segura (em termos de integridade referencial)
  • que exiga menos selects para recuperar a informação
    para resolver este problema?

Detalhe: sem utilizar procedimentos armazenados nem funções específicas de algum gerenciador de banco de dados.

Já pensamos nas seguintes soluções:

  • guardar um campo com a lista de IDs dos pais e filhos. Difícil de manter a integridade.
  • manter uma tabela secundária guardando toda a informação. Exige vários selects.

Alguma sugestão?

Valeu pessoal :smiley:

13 Respostas

MarcioTavares

Que susto… achei que fosse com a namorada :mrgreen: :lol:

Não consegui visualizar direito o problema. Coloca um exemplo prático aqui, beleza?

:thumbup:

_fs

hehe :smiley:

Categoria1
    - subCategoria1
    - subCategoria2
        - subsubCategoria1
            - subsubsubCategoria1
        - subsubCategoria2
    - subCategoria3

E, pra piorar, uma categoria qualquer pode ter mais de um pai.

jgbt

qual o banco?
o oracle tem consulta hierarquica.

[]'s

mister_m

LIPE:
hehe :smiley:

Categoria1
    - subCategoria1
    - subCategoria2
        - subsubCategoria1
            - subsubsubCategoria1
        - subsubCategoria2
    - subCategoria3

E, pra piorar, uma categoria qualquer pode ter mais de um pai.

Se as categorias podem ter mais de um pai, fica mais difícil de responder sua pergunta sem dados exatos. Quais são seus requerimentos de pesquisa? Que tipos de pesquisa você vai fazer nesta árvore?

M

Boa Pergunta :smiley:


Eu tenho a mesma situação aqui, com explosão de Produtos para o PCP, eu resolvi isto com uma função recursiva em Java (4 linhas de codigo).


Não sei se esta é a melhor solução, mas para mim resolveu.

[]s Mauro Schneider

F

Olá,

Na minha opniao fazer isso com SQL sem usar recursos de consulta hierarquica é algo que pode ficar ilegivel pra qualquer mortal.

]['s

boaglio

O Oracle oferece o recurso de “start with” com “connect by prior”

Consulte esse post do Site do AskTom

:wink:

smota

éeee Lipe, tu tá enrascado.

Os principais bancos tem um suporte bacana pra isso, que tal fazer pro seu banco e depois pensar nos demais?

Pra SQL Server veja isto: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/acdata/ac_8_qd_14_5yk3.asp
(yeap, MS powered)

Pra Oracle tem hierarchical_query_clause no SELECT.

Já vi soluções para PostgreSQL e DB2 (no estilo da MS, com SP)

F

boaglio:
O Oracle oferece o recurso de “start with” com “connect by prior”

Consulte esse post do Site do AskTom

:wink:

É “start with” do Oracle é lindo, mas quebra um dos requisitos do LIPE. :cry:

M

Eu testei este tipo de coisa com Oracle, e fica muitoooo lento.

boaglio:
O Oracle oferece o recurso de “start with” com “connect by prior”

Consulte esse post do Site do AskTom

:wink:

_fs

Pessoal, obrigado pelas respostas. Quanto às funções específicas de bancos, realmente não iremos usar. Obrigar o cliente a comprar um software mais caro que o produto em si não tem condições hehe

mister_m, o lance de um nodo ter mais de um pai precisa funcionar de maneira parecida às tags do Gmail. São filtros simples, com no próprio Gmail: “retorne todos os emails que tem a tag ‘trabalho’”. Só que em nosso caso as tags possuem outras informações.

Pelo que percebo até o momento a solução mais adequada é recuperar a informação com vários selects e a tabela de apoio. O que não seria tão ruim, já que a quantidade de níveis dificilmente passa de 4 ou 5.

louds

Otimize para o caso mais comum então…

table tag { 
ID int primary key,
NOME char(50) not null
}

table rel {
ID_CHILD int primary key,
ID_PARENT int primary key
}

#TODO parentes ate 5 niveis 
select * from rel as A
outer join rel as B on (A.ID_PARENT = B.ID_CHILD)
outer join rel as C on (B.ID_PARENT = C.ID_CHILD)
outer join rel as D on (C.ID_PARENT = D.ID_CHILD)
outer join rel as E on (D.ID_PARENT = E.ID_CHILD)
outer join rel as F on (E.ID_PARENT = F.ID_CHILD)
where
A.ID_CHILD in ( :leaves_id )

Coloca as foreign keys, um check/trigger/?? para evitar ciclos e o banco vai sempre estar íntegro.

Sobre a query. Vai dar trabalho extrair os dados dela, mas é factivel.

Essa query é executada primeiramente com o id que você quer e repetidamente com as folhas do passo anterior ate retornar vazio.

louds

Seu problema é igual ao de representar digrafos conexos assíclicos. Procura sobre isso no google.

Criado 15 de abril de 2005
Ultima resposta 15 de abr. de 2005
Respostas 13
Participantes 9