Acabei de ler um artigo de blog interessante sobre a ordenação do conjunto de resultados definido pelo usuário.
Alguns aplicativos, como listas de tarefas, precisam manter uma ordem de itens definida pelo usuário. O desafio é que a ordem é arbitrária e pode mudar quando o usuário reorganiza os itens
Uma tabela de exemplo poderia ser assim:
create table items
(
itemid int primary key,
itemdata varchar(200),
...
...
userorder ???
);
Com uma possível consulta de recuperação de:
select * from items order by userorder asc;
Há alguma abordagem que eu deva considerar, já que gostaria de manter as atualizações no mínimo, atualizações atômicas e consultas de recuperação o mais simples e "desempenhadas" possível?
Meu pensamento inicial era usar uma TIMESTAMP
coluna extra e atualizar apenas userorder
e os timestamp
valores para uma única linha (com a consulta de recuperação usando ORDER
ing by userorder asc, usertimestamp desc
), mas isso falha quando você precisa mover uma linha entre duas outras linhas que têm o mesmo valor .
Nenhum banco de dados específico em mente, pois eu mesmo uso um amplo espectro.
Eu penso nisso como uma variação esotérica da abordagem "True Fractions" naquela postagem do blog - a vantagem é que não há necessidade de introduzir um tipo definido pelo usuário (pelo menos se você estiver usando o Postgres).
Isso funciona usando as propriedades de ordenação natural
varbit
e mapeando uma sequência delas em uma árvore binária, de modo que sempre seja possível gerar outrovarbit
valor entre quaisquer dois valores adjacentes existentes:dbfiddle aqui
Se você carregar inicialmente muitas linhas ordenadas, talvez queira usar algum outro algoritmo para gerar os
userorder
valores iniciais, pois atingirá o pior caso para uso de espaço (cada linha usará um bit a mais douserorder
que a linha anterior). Você pode percorrer valores de mesmo comprimento para um número suficientemente grande de bits (por exemplo, para 8 valores:B'0001'
,B'0011'
,B'0101'
,B'0111'
,B'1001'
,B'1011'
,B'1101'
,B'1111'
).Introdução
Algumas linguagens BASIC realmente antigas exigiam um número de linha para cada linha de código.
Ao programar, os números de linha eram normalmente espaçados em múltiplos de 10. Isso permitia que você adicionasse mais código entre as linhas posteriormente.
Sua
items
tabela deve seguir o mesmo conceito.Algoritmo básico
userorder
começar como múltiplos de 10 começam com 10 para cadauserid
userorder
conforme necessáriouserorder
usando o Analyticscommit
os dados mudam.Código de renumeração
Isso é basicamente o que eu usei:
Estou assumindo que esta tabela contém a lista TODO de todos e cada usuário é identificado por
userid
.Este exemplo usa
ROW_NUMBER()
do Oracle. Você terá que substituí-lo por qualquer RDBMS que estiver usando.