| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 15/01/2009 13:56:13
|
peczenyj
Moderador
![[Avatar]](/images/avatar/299dc35e747eb77177d9cea10a802da2.jpg)
Membro desde: 26/03/2006 23:25:37
Mensagens: 3191
Localização: Rio de Janeiro
Offline
|
Senhores,
Estou com uma duvida técnica/concentual: preciso fazer um mecanismo de ordenação de entidades.
Imaginem que são Selos em uma Coleção. Tenho a tabela Colecao e a tabela Selo e um Selo esta em uma Colecao.
A ordem que estas fotos aparecem na Coleção pode ser alterada arbitrariamente, na tela o caboclo pode arrastar e soltar as fotos.
Pensei em implementar uma lista encadeada (cada selo sabe qual é o id do proximo) pois assim apenas alguns selos seriam afetados, ao arrastar um eu teria que desfazer apenas 2 nós ao inves de update em 9 ou 25 ou TODOS os selos por exemplo (e na exclusão recriar um nó). Guardar a ordem em um atributo da tabela de coleção me parece ruim.
Como eu vou fazer isso via PHP acessando Mysql eu pergunto:
1) Eu poderia ordenar pelo SQL usando algo macabro e específico do mysql para retornar os elementos conectados entre si.
2) Montar essa lista encadeada em memória, via PHP, seria ruim ou menos performático? Sem falar que eu teria que trazer sempre todos, mesmo em caso de paginação, ugh.
3) SQL recursivo ou algo mais complexo?
4) Poderia abandonar essa ideia e tratar a ordem como um numero e ordenar por ele, mas ai ao alterar uma posição eu teria que alterar todos os envolvidos, sera que vale a pena (penso em seguir por essa ideia)?
5) Poderia criar uma XREF maluca e uma maçaroca de SQL que traz tudo ordenado por acaso, uma vez que não faz sentido (via programação por BRUTEFORCE).
Então: sugestões, ofensas, comentários?
|
http://pacman.blog.br
'Não importa quanto alguém se dedique à tarefa. Ninguém consegue fazer a água da cascata cair para cima.' |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 15/01/2009 14:19:32
|
Leonardo3001
GUJ Ranger
Membro desde: 04/07/2007 18:28:58
Mensagens: 975
Offline
|
Pra banco de dados, o conceito de lista ordenada não existe. Ponto final.
Olhando o seu problema, me veio à cabeça a "solução BASIC". É assim: você vai usar uma coluna da tabela para definir a ordem, onde a linha com número de menor valor vem antes da linha com número de maior valor. Até aí tudo bem.
O "pulo do gato" é que você não vai atribuir 1, 2, 3 e assim por diante, mas 100, 200, 300... ou seja, números com bastante espaçamento entre si.
Quando você tiver que colocar uma nova foto entre duas adjacentes, cujos "order_number" sejam, por exemplo, 400 e 500; você atualizará o "order_number" da nova foto para 450, ou seja, a média entre os dois (como no BASIC).
Pode haver um problema se o cara fizer arrasta-e-solta muito frequentemente. Talvez chega-se a um momento em que os números adjacentes fiquem próximos demais (do tipo: 1455 e 1456) e não dê pra adicionar uma foto no meio. Aí precisará incrementar por um a foto de "order_number" maior pra caber. E isso continua até achar um número vago.
Não sei se você entendeu, mas é isso aí. Qualquer dúvida, pergunte.
|
Leonardo Veríssimo
-------------------------------------------------
Objectzilla |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 15/01/2009 14:35:08
|
Proteu Alcebidiano
JavaEvangelist
![[Avatar]](/images/avatar/ceccbaaff99be20a857e00767f70b481.jpg)
Membro desde: 23/06/2006 14:38:34
Mensagens: 391
Localização: Cidadão do Mundo
Offline
|
O que tu pode fazer, semelhante à alternativa 2 que você sugeriu, em caso de você não se preocupar mais com o desempenho do que com uso de memoria, é combinar uma lista encadeada com um map de chaves com valores fixos e guardar cada chave de valor fixo do map dentro de cada object que representa o selo.
Dessa Forma, você alia busca rapida (pelo indice você encontra o selo correspondente) e reordenação sem precisar reindexar. Para buscar um selo, você dá apenas um get associado a posicao, que é sempre fixa; no momento de trocar os selos, você usa o get para achar os selos que sofrerão a troca (e essa troca você faz como numa lista encadeada qualquer) e em seguida atualiza os indices de DENTRO do selo sempre mantendo a chave fixa para busca.
T+
|
Glaucio G. de M. Melo
Don't run Alone.
[gm]² on forecasting
The world is parallel, and yet most often we program real-world applications in sequential programming languages. This is unnecessarily difficult. (Joe Armstrong). |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 15/01/2009 14:54:47
|
peczenyj
Moderador
![[Avatar]](/images/avatar/299dc35e747eb77177d9cea10a802da2.jpg)
Membro desde: 26/03/2006 23:25:37
Mensagens: 3191
Localização: Rio de Janeiro
Offline
|
Leonardo3001 wrote:Olhando o seu problema, me veio à cabeça a "solução BASIC". É assim: você vai usar uma coluna da tabela para definir a ordem, onde a linha com número de menor valor vem antes da linha com número de maior valor. Até aí tudo bem.
O "pulo do gato" é que você não vai atribuir 1, 2, 3 e assim por diante, mas 100, 200, 300... ou seja, números com bastante espaçamento entre si.
Quando você tiver que colocar uma nova foto entre duas adjacentes, cujos "order_number" sejam, por exemplo, 400 e 500; você atualizará o "order_number" da nova foto para 450, ou seja, a média entre os dois (como no BASIC).
Eu tinha pensado nessa solução porem de tempos em tempos eu poderia fazer um refresh nessa lista caso ocorrece isso de um order number ficar muito proximo.
Imagino que nessa situação,
SELO{id=1, posicao=100}
SELO{id=2, posicao=200}
SELO{id=3, posicao=300}
SELO{id=4, posicao=400}
Se eu quisesse colocar o id 4 no lugar do id 2, empurrando o id 2 para baixo, deixando id 3 pro fim eu teria que fazer
SELO{id=1, posicao=100}
SELO{id=4, posicao=150}
SELO{id=2, posicao=200}
SELO{id=3, posicao=300}
Imagino que, o que eu preciso saber é: vou ficar entre quem e quem. Vou considerar essa solução, até pq não posso implementar nada muito complexo pois testar isso não sera facil pelo pouco tempo que tenho pela frente. Agora vou analisar a solução do MAP do proteu
|
http://pacman.blog.br
'Não importa quanto alguém se dedique à tarefa. Ninguém consegue fazer a água da cascata cair para cima.' |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/01/2009 12:24:34
|
Proteu Alcebidiano
JavaEvangelist
![[Avatar]](/images/avatar/ceccbaaff99be20a857e00767f70b481.jpg)
Membro desde: 23/06/2006 14:38:34
Mensagens: 391
Localização: Cidadão do Mundo
Offline
|
Vou te dar uma ideia de mapping que pode ajudar:
imagina que o estado inicial é esse:
0 1 2 3 4
considere que o mapping é "entre quem e quem um numero está situado":
0 -> (0,0)
1 -> (1,1)
2 -> (2,2)
3 -> (3,3)
4 -> (4,4)
se eu quiser colocar o 4 entre a primeira e a segunda posicao, ficaria assim:
0 -> (0,0)
1 -> (1,1)
2 -> (2,2)
3 -> (3,3)
4 -> (1,2)
a partir daí, teria que pensar como fazer adiante
T+
|
Glaucio G. de M. Melo
Don't run Alone.
[gm]² on forecasting
The world is parallel, and yet most often we program real-world applications in sequential programming languages. This is unnecessarily difficult. (Joe Armstrong). |
|
|
 |
|
|
|
|