2016-06-30 25 views
10

Ho un sistema software di fatturazione telefonica. In esso ci sono registri giornalieri delle chiamate degli utenti. I log sono partizionati orizzontalmente per data (mese). Ogni partizione viene archiviata in un database separato e può essere distribuita su più istanze.Come ordinare i dati partizionati orizzontali

Nell'interfaccia utente l'utente specificherà un intervallo di date. I dati restituiti possono essere ordinati su qualsiasi campo. L'intervallo di date può estendersi su più partizioni. L'applicazione deve supportare il paging attraverso i dati dell'intervallo di date.

Non riesco a caricare troppi record in memoria per l'ordinamento. Mettere l'ordinamento all'interno della query mi dà solo dati ordinati all'interno di un set di risultati.

Quindi ho bisogno di ordinare i dati da più partizioni che sono ordinate individualmente. Come posso restituire i record ordinati all'interfaccia utente da più set di risultati ordinati?

MODIFICA: Dopo ulteriori analisi su questo problema, abbiamo ulteriori input. C'è anche bisogno di paginazione. Per questo motivo abbiamo bisogno di trovare un altro modo per fare l'ordinamento in tempo reale su più set di risultati.

+1

È possibile caricare solo la colonna da ordinare e gli ID record, quindi ordinare e infine caricare i record che si desidera visualizzare in base agli ID ordinati. Non sono sicuro che potresti fare un interleaving significativo su un livello db, quindi farlo nel tuo codice sembra essere il modo più semplice. Un'altra opzione potrebbe essere quella di scrivere i record (parziali) in un file mappato in memoria e ordinarli, ma questo probabilmente costerebbe anche più prestazioni - dopotutto si tratta di una classica situazione di velocità-vs-memoria qui. – Thomas

+0

Abbiamo discusso il primo approccio, ma il lato negativo in questo approccio è che dobbiamo interrogare nuovamente con Id e, poiché è da interfaccia utente, anche l'impaginazione deve essere raggiunta. –

+1

Beh, abbiamo avuto una situazione simile in cui il caricamento di tutti i dati richiedeva troppa memoria e quindi abbiamo seguito l'approccio del primo caricamento solo dei dati da ordinare e degli ID, quindi di ordinare e conservare solo gli ID. Il cercapersone opererebbe quindi sugli ID ordinati e solo i record corrispondenti agli ID di una pagina verrebbero caricati completamente. Ovviamente avresti bisogno di interrogare ancora ma con il paging dovresti farlo comunque. Per accelerare la seconda query (di paginazione) è possibile memorizzare anche la partizione di origine e interrogare solo quelle partizioni. – Thomas

risposta

2

Facendo affidamento sulla capacità di ResultSet di caricare dati limitati in memoria, siamo in grado di trovare una soluzione in Java utilizzando Dynamic Comparator. La soluzione è di prendere il primo record da ogni resultSet e ordinarlo in java e restituire il primo elemento dai dati ordinati.

soluzione dettagliata:

In primo luogo abbiamo costruito un programma che ci può dare un comparatore dymanic rispondono a questi criteri choosed sullo schermo.

Secondo È stato scritto un wrapper AggregateResultSet su DAO che si sta avvolgendo su ResultSet da diverse partizioni. Nota: questi singoli ResultSet sono già ordinati con gli stessi criteri. Quindi AggregateResultSet verrà fornito un comparatore dinamico.

Questo AggregateResultSet avrà una struttura dati per memorizzare inizialmente il primo elemento di ciascun set di risultati. Restituirà il prossimo elemento in chiamata a next(). Questo elemento sarebbe l'elemento che viene prima come per dynamicComparator. Durante la chiamata next(), rimuoviamo questo elemento dalla struttura dati temporanea e inseriamo l'elemento successivo dallo stesso set di risultati nella struttura dati temporanea. In questo modo, AggregateResultSet restituirà i dati nell'ordine previsto, unendo/memorizzando/ordinando dati molto limitati in Java.

Speriamo di non ricevere alcun problema di confronto dato che abbiamo in gran parte dati numerici/stringa nell'ordinamento.

+1

Sembra una soluzione interessante che dovrebbe ridurre il sovraccarico della memoria nell'applicazione Java. Non sono sicuro delle implicazioni per i database anche se in teoria dovresti mantenere la connessione aperta e mantenere il risultato nella cache del db per recuperare rapidamente l'elemento successivo. Inoltre, potresti incontrare problemi di transazione se i dati che il db conserva nella sua cache vengono aggiornati. – Thomas

+0

@Thomas, poiché è un sistema di fatturazione, i dati (record di chiamata) vengono caricati solo una volta (giorno + 2) dopo che i dati sono stati riconciliati a vari livelli e mai aggiornati (sicurezza). –

+0

Se capisco correttamente la tua soluzione, il paging sarà molto inefficiente, dal momento che dovresti leggere tutte le pagine 'n-1' prima della pagina' n'. –