[OFF] MYSQL - relacionamento polimorfico

375 views
Skip to first unread message

Brunno dos Santos

unread,
Aug 15, 2011, 12:39:50 PM8/15/11
to php-b...@googlegroups.com
Aproveitando a onde de dúvidas sobre MySQL que ta rolando aqui na lista, resolvi entra com uma discução a respeito de relacionamentos polimorficos.
Eu gostaria de saber como vocês tratartiam o exemplo abaixo:

Tabelas:
  • noticias
  • midias
  • comentario
Partindo do principio que essas três "entidades" podem ser comentáveis, como vocês modelariam o banco?? Colocariam uma coluna 'tipo' varchar, onde estaria ecrito se o comentário é de noticia, mídia ou de outro comentário?? Criariam uma outra tabela que teria ID e Tipo e fariam o relacionamento com FKs??

Brunno dos Santos

Back-End Developer
11 - 7666-4358


abstraindo.com | Extensões Para Firefox | @squiter

Paulo Augusto Teixeira

unread,
Aug 15, 2011, 2:26:38 PM8/15/11
to php-b...@googlegroups.com
Um opção que me veio a cabeça agora. Sem muitas análises, é a tabela comentário ser a entidade principal.

E as outras terem uma FK dela, incluindo ela. O chamado Auto-relacionamento.

Tem que se pensar principalmente no desempenho, mais do que no padrão.

2011/8/15 Brunno dos Santos <squi...@gmail.com>

--
Você está recebendo esta mensagem porque se inscreveu no grupo "php-brasil" dos Grupos do Google.
Para postar neste grupo, envie um e-mail para php-b...@googlegroups.com.
Para cancelar a inscrição nesse grupo, envie um e-mail para php-brasil+...@googlegroups.com.
Para obter mais opções, visite esse grupo em http://groups.google.com/group/php-brasil?hl=pt-BR.



--
Paulo A. Teixeira
Adobe Certified Expert Flex 3 with AIR
Adobe Certified Expert Rich Internet Application v1.0
Adobe Certified Expert ColdFusion 8
--
Blog: http://www.pauloteixeira.blog.br
My Pics: http://agostinho.tumblr.com/

Rodrigo Mendonça

unread,
Aug 15, 2011, 2:42:32 PM8/15/11
to php-b...@googlegroups.com
na entidade comentarios vc criar dois campos

comentavel_type = varchar
comentavel_id = int

comentavel_type pode ser Comentario, Noticias, Midias (coloque em maiusculo e sem acentos pra representar a classe do model)
comentavel_id = é o id do recurso

então se comentavel_type = Comentario ele se comporta como um auto relacionamento..

O Rails (framework do ruby) trata muito bem associação polimórfica, esse padrão que eu disse acima é o padrão do rails que funciona mto bem

sacou??
Rodrigo Mendonça
(62) 8567-3142

André da Silva Severino

unread,
Aug 15, 2011, 2:55:54 PM8/15/11
to php-b...@googlegroups.com
[OFF]

A onda de dúvidas sobre MySQL. 

Desculpa é que nos últimos 5 dias fiz umas 10 perguntas sobre mysql aqui. :xxxx

Att,

André da Silva Severino
Desenvolvedor web
(19) 8847.3747

Brunno dos Santos

unread,
Aug 15, 2011, 3:09:17 PM8/15/11
to php-b...@googlegroups.com
Oi Rodrigo, é exatamente por culpa do Rails que eu estava pensando se isso seria bacana! hehehehhe
É aí que entra a minha dúvida, é bacana termos um campo com o nome da "entidade" em todas os registros de comentário mesmo? Essa seria uma boa solução para uma aplicação grande?

E André, não precisa se preocupar a galera aqui sempre tem disposição em ajudar o pessoal ;)


Brunno dos Santos

Back-End Developer
11 - 7666-4358


abstraindo.com | Extensões Para Firefox | @squiter



2011/8/15 André da Silva Severino <andredasil...@gmail.com>

Rodrigo Mendonça

unread,
Aug 15, 2011, 3:22:55 PM8/15/11
to php-b...@googlegroups.com
Cara acredito eu que essa solução é a melhor, pois você vai estar utilizando somente dois campos. Não esquece de criar os indexes no banco de dados pra não perder a performance já que pelo jeito vai ter mtos registros

Paulo Augusto Teixeira

unread,
Aug 15, 2011, 5:09:45 PM8/15/11
to php-b...@googlegroups.com
É exatamente por ter muitos registros que eu não optaria por ter um campo varchar redundante no meu banco.

Nesse caso em especifico eu faria uma tabela de domínio com 3 registros e chaves indexadas... bem mais produtivo para o servidor.

2011/8/15 Rodrigo Mendonça <den...@gmail.com>

Brunno dos Santos

unread,
Aug 15, 2011, 5:32:32 PM8/15/11
to php-b...@googlegroups.com
Eu queria chegar nesse tipo de discução mesmo Paulo!
Você criaria uma tabela com os campos ID, tipo e entidade que seria uma FK para o ID da entidade, é isso??
E quando fosse fazer as buscas usaria um JOIN mesmo? Essa solução é mais interessante para o servidor?


Brunno dos Santos

Back-End Developer
11 - 7666-4358


abstraindo.com | Extensões Para Firefox | @squiter



2011/8/15 Paulo Augusto Teixeira <pauloa...@gmail.com>

André Moreira

unread,
Aug 15, 2011, 8:48:31 PM8/15/11
to php-b...@googlegroups.com
Entre join e redundância, eu acho que a junção é mais custosa, mas como só vão ter 3 registros na outra tabela, creio que não será tão custosa assim.

Paulo Augusto Teixeira

unread,
Aug 16, 2011, 10:15:53 AM8/16/11
to php-b...@googlegroups.com
Brunno, essa minha sugestão é para a segunda forma sugerida... Eu (Paulo) se tivesse que implementar esse tipo de solução no banco, eu implementaria utilizando a entidade comentarios como a entidade principal.

E todas as outras teriam FK de comentarios. Incluindo ela mesma.

A segunda opção eu sugeri como solução mais viável para  a idéia do Rodrigo.

Eu entendo que é a solução que o Rails usa... mas quem disse que o Rails está certo?

Num banco com 300 registros e 500 acessos vai funcionar de boa, mas em casos de milhões tanto de registros quanto de acessos... aí a questão é outra.

Eu penso a longo prazo!

Brunno dos Santos

unread,
Aug 16, 2011, 10:35:07 AM8/16/11
to php-b...@googlegroups.com
Entendi Paulo, então se eu tiver uma aplicação com mais acessos (digamos uns 6.000/dia, graças a deus com esperança de aumento hehehe) seria mais interessante implementar com tabelas auxiliares para as FK.
No caso de noticias, por exemplo, eu teria uma segunda tabela comentarios_notcia com id_comentario e id_noticia (essas duas colunas como indexes) para fazer um relacionamento n-1, é isso mesmo né?

Descupem estar estendendo essa thread tanto, mas é que realmente estou preocupado em sobrecarregar os servidores do meu cliente com uma má implementação.


Brunno dos Santos

Back-End Developer
11 - 7666-4358


abstraindo.com | Extensões Para Firefox | @squiter



2011/8/16 Paulo Augusto Teixeira <pauloa...@gmail.com>

Cassiano Ricardo Mourão

unread,
Aug 16, 2011, 1:26:34 PM8/16/11
to php-b...@googlegroups.com
São essas 3 tabelas, só e somente?

Pra que complicar com mais uma tabela? Deixa só as 3 mesmo, sendo que em comentário você tem comentario_tipo, que pode ser 1, 2 ou 3 por exemplo. Na própria tabela você coloca um comentário dizendo que 1 é notícia, 2 é cometário e 3 é sei lá o que.

Brunno dos Santos

unread,
Aug 16, 2011, 1:54:35 PM8/16/11
to php-b...@googlegroups.com
Não não Cassiano, vão ter varias entidades que podem ser comentáveis, e cada um desses comentaveis podem ter vários comentários e por ai vai! hehehe

Pensando rápido chego num número de umas 7 entidades comentáveis em meu sistema.


Brunno dos Santos

Back-End Developer
11 - 7666-4358


abstraindo.com | Extensões Para Firefox | @squiter



2011/8/16 Cassiano Ricardo Mourão <cassian...@gmail.com>
ário você tem comentario_tipo, que

Paulo Augusto Teixeira

unread,
Aug 16, 2011, 2:03:00 PM8/16/11
to php-b...@googlegroups.com
Brunno você ainda não entendeu.

Não precisa de três tabelas auxiliares.

A estrutura seria:

- Noticias
   -> Id
   -> comentarioId
   -> titulo

- Midias
   -> Id
   -> comentarioId
   -> titulo

- Comentarios
   -> Id
   -> comentarioId
   -> auxiliarId
   -> titulo

- ComentariosAuxiliar
   -> Id (1,2,3)
   -> nome  (Noticias,Midias,Comentarios)

Toda vez que você fizer um select para buscar os comentários de notícias fará assim:

SELECT 
            c.Id as IdComentario, 
            c.titulo as TituloComentario, 
            c.descricao as DescricaoComentario 
FROM 
            comentarios c INNER JOIN ComentariosAuxiliar a 
            ON c.auxiliarId = a.Id AND a.Id = 1 


E do mesmo modo para mídias e comentarios
2011/8/16 Brunno dos Santos <squi...@gmail.com>

Paulo Augusto Teixeira

unread,
Aug 16, 2011, 2:04:44 PM8/16/11
to php-b...@googlegroups.com
Cassiano o problema disso, é que você que é o desenvolvedor, sabe que 1 é igual a notícias, 2 é igual a comentario e 3 é igual a sei lá oque.

O desenvolvedor que for dar manutenção no teu código daqui a 10 anos, não saberá.

Para esse tipo de coisas é que existem os padrões.

2011/8/16 Cassiano Ricardo Mourão <cassian...@gmail.com>
São essas 3 tabelas, só e somente?

Cassiano Ricardo Mourão

unread,
Aug 16, 2011, 2:18:42 PM8/16/11
to php-b...@googlegroups.com
Nossa! Não sabia que os padrões existiam pra isso.
Na verdade, pra isso que existe uma coisa chamada documentação. E por isso mesmo que sugeri que ele adicionasse um comentário na tabela comentários relacionando os códigos com as "entidades".

Enfim, padrão existe pra, nesse caso, normalizar as tabelas. Coisa que sua sugestão não faz.

PELO QUE EU ENTENDI, uma notícia terá de 1 a n comentários. Cada um desses comentários poderá ter outro comentário que pdoerá ter outro e por aí vai.
No seu modelo, uma notícia só tem um comentário ou, necessariamente, os comentários seguintes terão de ser "filhos" de outros comentários.

Basicamente, minha sugestão pra o problema do topic starter é:

noticias (id,titulo,corpo)
midias(id,nome)
comentarios(id,pai_id,pai_tipo,comentario,autor,data)
tipos_entidades ou whatever(id,nome)


Exemplos, partindo do princípio que tipos_entidades:1-noticia,2-midia,3-comentario:

Notícia com 2 comentários
noticia(1, nome_noticia, corpo_noticia)
comentario(1,1,1,blablabla,cassiano,now())
comentario(1,1,1,blablabla2,cassiano2,now())

Mídia com 4 comentários sendo que o 2º comentário possui 1 comentário
midia(1, nome_midia)
comentario(3,1,2,comentário 1,autor,now())
comentario(4,1,2,comentário 2,autor,now())
comentario(5,1,2,comentário 3,autor,now())
comentario(6,1,2,comentário 4,autor,now())
comentario(7,4,3,comentário do 2º comentário,autor,now())

Comentário é uma "entidade"? Existe uma página chamada "Comentários"?
comentario(4,3,null,comentário sem pai? então esse é uma 'entidade',autor,now())


Não vi motivo de tanta complicação.

Paulo Augusto Teixeira

unread,
Aug 16, 2011, 2:50:38 PM8/16/11
to php-b...@googlegroups.com
Cassiano,

Se vc soubesse ao menos oque está falando, para a gambiarra que vc sugeriu existe ENUM.

Passar bem!

Cassiano Ricardo Mourão

unread,
Aug 16, 2011, 2:53:00 PM8/16/11
to php-b...@googlegroups.com
gambiarra... lol.

Brunno dos Santos

unread,
Aug 16, 2011, 3:29:18 PM8/16/11
to php-b...@googlegroups.com
Calma gente sem estresse! hehehhehehehe
Eu entendi sim o que você sugeriu Paulo, foi quase o que eu pensei a principio mas não sabia se era o mais recomendado mesmo, por isso lancei o tópico, para ouvir a opinião de mais gente =)

Enfim, minhas dúvidas foram respondidas podemos encerrar o tópico pra não gerar desavenças!!

Muito obrigado a todos =)



Brunno dos Santos

Back-End Developer
11 - 7666-4358


abstraindo.com | Extensões Para Firefox | @squiter



2011/8/16 Cassiano Ricardo Mourão <cassian...@gmail.com>

Rodrigo Mendonça

unread,
Aug 16, 2011, 4:31:29 PM8/16/11
to php-b...@googlegroups.com
Só uma última dica. Seria melhor usar postgres se for pra ter tantos registros assim, ele é mais performatico com grande volumes de dados
Reply all
Reply to author
Forward
0 new messages