Implementa l'impaginazione che memorizza da dove eravamo rimasti?

7

Selezioniamo una tabella di database delle relazioni (ad esempio una tabella di controllo) con un alto tasso di scrittura. Possiamo visualizzare 100 record alla volta. Ma poiché un utente non vuole vedere alcuni record a pagina 1 a pagina 2 quando vengono aggiunti un paio di nuovi record.

Ho pensato al caching, ma possiamo mantenere così tanto su un server cache come memcache o redis e invalidare la memorizzazione nella cache è davvero difficile (immagina che l'utente apra una nuova scheda ora dobbiamo occuparci di due sessioni): qual è lo standard implementare l'impaginazione che può riprendere da dove avevamo lasciato? Tenere premuto il cursore alla fine avrebbe esaurito tutte le connessioni nel pool.

Un limite o intervallo di navigazione non funzionerà a causa dell'elevato tasso di scrittura.

    
posta CppLearner 18.04.2016 - 22:50
fonte

1 risposta

1

Dovrai mettere in cache qualcosa da qualche parte, sia che usi il db per farlo con un cursore, sia che lo faccia esterno al db.

Tuttavia, se hai il pieno controllo del db e del suo schema, potresti fare un po 'di cache delle righe e delle età delle righe all'interno delle tabelle stesse.

Potresti incorporare un timestamp o una colonna del numero di versione nella tua tabella che ti aiuterebbe a ottenere un'istantanea ragionevole delle righe senza una transazione di lunga durata (cioè il cursore) di fronte a aggiornamenti costanti.

Quindi, è possibile utilizzare query separate per ogni pagina = N, ognuna delle quali fornisce lo stesso timestamp o il numero di versione per il sistema da utilizzare insieme nella clausola where, in modo tale che solo le informazioni valide da quel punto vengano restituite indipendentemente da quale numero di pagina viene richiesto e di nuove righe inserite.

Se vengono eliminate anche le righe, dovrai lasciarle in posizione per conservare l'istantanea e semplicemente contrassegnarle come cancellate da quando / quale versione; un confronto di eliminazione sarebbe quindi utilizzato anche in congiunzione nella clausola where. (Puoi creare una vista da utilizzare per tutti gli altri scopi che omettono le righe cancellate.)

Se le eliminazioni vengono solo contrassegnate e non effettivamente eseguite, avresti una fonte di "perdita di memoria", ma potrebbe essere meglio che non eseguire i cursori. (Potresti desiderare una qualche forma di "GC" per pulire regolarmente le vecchie eliminazioni, supponendo che non vuoi supportare tornare indietro nel tempo.)

Se anche le righe vengono modificate, stai entrando abbastanza in profondità, ma potrebbe essere gestita eliminando (ovvero contrassegnando cancellato) l'originale e aggiungendo una nuova riga come sostituto. (La tua chiave primaria diventerà un problema che deve essere affrontato in qualche modo poiché avrai effettivamente duplicati).

Alcuni problemi potrebbero essere risolti avendo una tabella alternativa o duplicata con la colonna timestamp / versione # e rilassando alcuni vincoli su quella tabella. Le query di lunga durata utilizzerebbero quella tabella alternativa; gli aggiornamenti transazionali userebbero la tabella originale e ci sarebbe un meccanismo per alimentarne uno dall'altra.

Fondamentalmente, questa sarebbe la versione manuale / poorman dell'isolamento dello snapshot. Potrebbe essere meglio usare i cursori ... e terminare quelli troppo longevi.

    
risposta data 18.04.2016 - 23:36
fonte

Leggi altre domande sui tag