Eu tenho um banco de dados MySQL, por exemplo,
EU IA | TÃtulo | Compra_Em |
---|---|---|
1 | TÃtulo A | 01/12/2023 |
2 | TÃtulo B | 2023-08-22 |
3 | TÃtulo C | 01/12/2023 |
4 | TÃtulo D | 23/08/2023 |
5 | TÃtulo E | 01/12/2023 |
6 | TÃtulo F | 2023-06-22 |
7 | TÃtulo G | 01/12/2023 |
8 | TÃtulo H | 02/08/2023 |
Estou construindo carregamento infinito em ambas as direções.
Digamos que minha recuperação inicial seja SELECT * FROM table ORDER BY Purchase_At DESC LIMIT 3
e retorne os ID 1, 3 e 5.
Se eu quiser carregar alguma coisa antes do ID 1, eu faço SELECT * FROM table WHERE Purchase_At < '2023-12-01' ORDER BY Purchase_At DESC LIMIT 3
?
E vice-versa, carregando qualquer coisa depois das 5, eu faço SELECT * FROM table WHERE Purchase_At > '2023-12-01' ORDER BY Purchase_At DESC LIMIT 3
?
Como você pode ver, há chances de encontrar dados repetidos, pois a ordenação de vários registros com o mesmo valor não é confiável. Eu não posso fazer WHERE ID < 1
ou WHERE ID > 5
também.
Não posso usar a consulta de pagamento como LIMIT
ou OFFSET
porque durante a visualização do usuário, novos registros serão adicionados e isso atrapalhará a paginação.
Purchase_At é algo que o usuário inseriu através de um selecionador de data para a data de recebimento e pronto, não há milissegundo etc... Ano, Mês e Dia é tudo que tenho. No meu caso, poderia haver usuário com 10 recibos no mesmo dia. Se eu paginasse 3 por página, como posso garantir que meu carregamento infinito não produza dados repetidos?
Para facilitar a compreensão da minha pergunta, pense em um sistema de chat do Facebook. Onde o usuário rola para baixo para carregar novas mensagens e rola para cima para carregar mensagens antigas. Como posso conseguir o mesmo sabendo apenas que meu tipo pode ter vários valores Purchase_At com apenas ano, mês e dia.
Problema: sua coluna de data "Purchase_At" não é exclusiva, portanto, não pode ser usada como um Ãndice para buscar os resultados, e a ordenação por data não garante o retorno de linhas sempre na mesma ordem.
Solução: use (Purchase_At,id) em vez disso. Isso é único e terá um pedido estável.
Exemplo de DB Fiddle .
Obtenha as primeiras 3 linhas:
A última linha da consulta anterior tem (d,id)=('2000-01-02',2) então para obter a próxima linha, basta usar ">":
Um Ãndice multicolunas em (d,id) otimizaria esta consulta e evitaria uma classificação.