Uso Django e PostgreSQL, ma non sono assolutamente legato all'ORM Django se esiste un modo migliore per farlo con operazioni SQL o database specifiche.Struttura dati per la memorizzazione di un campo di ordinamento per consentire modifiche efficienti
Ho un modello che richiede un ordinamento sequenziale. Le operazioni di ricerca in genere recuperano l'intero elenco in ordine. L'operazione più comune su questi dati è quello di spostare una riga alla fine di un elenco, con un sottoinsieme degli elementi intermedi gorgogliare in sostituzione di quello precedente in questo modo:
(operation on A, with subset B, C, E) A -> B B -> C C -> E D -> D E -> A Notice how D does not move.
In generale, il sottoinsieme di articoli non saranno più di circa 50 voci, ma l'elenco di base potrebbe crescere fino a decine di migliaia di voci.
Il modo più ovvio di implementare questo è con un campo di ordine intero semplice. Questo sembra non ottimale. Richiede il compromesso di rendere la colonna degli ordini di posizione non univoca, laddove la non unicità è richiesta solo per la durata di un'operazione di modifica. Per vedere questo, immaginare l'operazione minima utilizzando A con sottoinsieme B:
oldpos = B.pos
B.pos = A.pos
A.pos = oldpos
Anche se hai memorizzato la posizione, in seconda linea che hai violato il vincolo di unicità. Inoltre, questo metodo rende problematica l'atomicità: l'operazione di lettura deve essere eseguita prima della scrittura, durante la quale i record potrebbero cambiare. La documentazione di default per la gestione delle transazioni di Django non risolve questo problema, anche se so che dovrebbe essere possibile in SQL usando il livello "REPEATABLE READ" del blocco delle transazioni.
Sto cercando strutture di dati alternative che si adattino meglio a questo schema di utilizzo. Ho esaminato lo this question per le idee.
Una proposta v'è la soluzione stile decimale Dewey, che rende le operazioni di inserimento verificano numericamente tra valori esistenti, quindi inserendo A tra B e C risultati in:
A=1 -> B=2 B=2 -> A=2.5 C=3 -> C=3
Questo risolve colonna problema unicità, ma introduce il problema che la colonna deve essere un float di un numero specificato di decimali. O sovrastimolo e immagazzino più dati di quanti ne abbia bisogno, oppure il sistema diventa limitato dalla lunghezza decimale arbitraria che impongo. Inoltre, non mi aspetto che l'uso sia anche oltre il database: alcune chiavi verranno spostate molto più spesso di altre, rendendo questa soluzione il più presto possibile. Potrei risolvere questo problema periodicamente ri-numerando il database, ma sembra che una buona struttura dati dovrebbe evitare di averne bisogno.
Un'altra struttura che ho considerato è la lista collegata (e le varianti). Questo ha il vantaggio di rendere le modifiche semplici, ma non sono sicuro delle sue proprietà rispetto a SQL - ordinare un elenco di questo tipo nella query SQL sembra come sarebbe doloroso, e l'estrazione di un sottoinsieme non sequenziale della lista ha terribili proprietà di recupero.
Oltre questo, ci sono alberi B, vari alberi binari e così via. Cosa consiglia per questa struttura dati? Esiste una struttura dati standard per questa soluzione in SQL? L'idea iniziale di andare con interi sequenziali avrà davvero problemi di ridimensionamento, o vedrò problemi dove non ce ne sono?
Lanciare una taglia qui a causa del basso numero di risposte ... –
Ciao Paul - vedo che hai accettato la mia risposta - grazie: D. Quale delle soluzioni proposte hai deciso di adottare e perché? – Matt