App web basata su MySQL: il modo più semplice per gli utenti di scegliere l'ordine o gli articoli?

Sto lavorando a qualcosa in cui gli utenti possono riorganizzare gli oggetti e in un secondo momento tali elementi devono essere visualizzati nell'ordine scelto. Come semplice esempio, considera un elenco di elementi:

A, B, C, D, E, F, G.
La tabella MySQL sarebbe qualcosa di semplice: user_id, letter, sortnumber

L'utente è autorizzato a modificare l'ordine in passaggi incrementali. Potrebbero spostare A a dopo D, G all'inizio, ecc. In aggiunta a ciò, possono aggiungere e rimuovere elementi. Potrebbero quindi eliminare C o aggiungere X. In ognuno di questi passaggi, invierò i dati a PHP, che li elaborerà e imposterà gli elementi in MySQL.

Ci sono due modi in cui vedo questo:

  1. Ogni volta che aggiungono / rimuovono / riordino qualcosa, invia l'integer elenco a PHP, cancella tutti i dati che avevano in precedenza e inserisci semplicemente il nuovo elenco. Il problema è che questo è un sacco di cancellazioni / inserimenti each volta che fanno qualcosa. Potrebbero spostare A su B, e poi improvvisamente cancellerò 7 record e inserirò altri 7. Tra i lati positivi, è semplicemente semplice.
  2. Ogni "spostamento" che fanno (ad esempio: un add, o una rimozione, o un riordino), invia le informazioni per quello. EG, hanno spostato A dopo F e mi dicono "sposta A dopo F". Ora devo controllare che sia A sia F siano presenti nell'elenco, quindi devo diminuire tutti i "numbers di sorting" tra A e F (inclusa F). Se dicono "cancella Z" devo trovarlo sulla list, cancellarlo e decrementare tutti i numbers di serie dei record dopo di esso.

Quindi sono solo curioso … qualcuno ha avuto a che fare con qualcosa in cui l'ordine conta, e se sì, come è andata?

Aggiungi una colonna Sequenza alla tabella – come numero a virgola mobile.

Quando un elemento viene spostato tra la row A e la row B, imposta il numero di sequenza sulla media delle colonne adiacenti

Indicizza la colonna Sequenza 🙂

Quando l'utente desidera salvare il nuovo ordine degli articoli, confrontarlo con il nuovo ordine con il vecchio ordine e eseguire solo gli aggiornamenti su quelli che hanno cambiato il loro numero di sorting . Se eliminano un object, non è necessario spostare il numero di serie in basso. Se si ordina una list con un numero mancante nel mezzo, sarà comunque nell'ordine corretto.

L'ordine di sequenza finale è l'unico che conta. Se sposti sei oggetti per get un ordine particolare, non hai davvero bisogno di preoccuparti di quale sia la sequenza della list nei punti tra come era quando hai iniziato e come è quando hai finito.

Aggiungi e rimuovi elementi senza preoccuparti dell'ordine della sequenza, quindi aggiorna gli elementi per impostare il valore della sequenza quando fai clic su un button che dice "Salva sorting".

Questo ti dà due vantaggi:

  • È molto less sovraccarico each volta che cambi un object, il che significa anche che sarà più veloce.
  • È semplicissimo impostare la sequenza: tutto ciò che devi fare è submit una list degli ID dell'articolo nell'ordine desiderato e poi scorrere su di essa, aggiornando il valore della sequenza a partire da 0 e salendo.

Ecco la stessa risposta che ho dato alla domanda di Thomaschaaf:

Questo non è un problema facile. Se hai un numero basso di elementi ordinabili, li reimposteresti tutti al loro nuovo ordine.

Altrimenti, sembra che ci vorrebbe tanto lavoro o più per "test-and-set" per modificare solo i record che sono stati modificati.

Potresti debind questo lavoro al lato client. Chiedete al cliente di mantenere il vecchio sorting e il nuovo sorting e determinare quale row [sorting] deve essere aggiornata, quindi passa tali tuple all'interface PHP-mySQL.

Potresti migliorare questo metodo nel modo seguente ( non richiede float):

  1. Se tutti gli elementi ordinabili in una list sono inizializzati in un sorting in base alla loro posizione nell'elenco, impostare l'sorting di each elemento su qualcosa come row [sorting] = row [sorting * K] where K è un numero> numero medio di volte in cui ci si aspetta che l'elenco venga riordinato. O (N), N = numero di elementi, ma aumenta la capacità di inserimento di alless N * K con alless K slot aperti tra ciascuna coppia di elementi in output.

  2. Quindi se vuoi inserire un elemento tra due altri è semplice come cambiare il suo sorting per essere uno che è> l'elemento inferiore e <il superiore. Se non c'è una "stanza" tra gli elementi, è sufficiente riapplicare l'algorithm "spread" (1) presentato nel paragrafo precedente. La K più grande è, less spesso sarà applicata.

L'algorithm K verrebbe applicato selettivamente nello script PHP mentre la scelta del nuovo sorting sarebbe eseguita dal client (Javascript, forse).

Avere una chiave primaria e un numero per each object. Se si dispone di un arrays php che include le chiavi primarie, è ansible rimuovere elementi e inserire elementi nell'arrays utilizzando arrays_splice ().

// base arrays $items = arrays( 7, 11, 9, 4, 5); // remove item 11 arrays_splice($items, arrays_search(11), 1); // insert 11 before item 4 arrays_splice($items, arrays_search(4), 0, 11); // input now contains 7, 9, 11, 4, 5 

Quindi esegui un ciclo attraverso la matrix e aggiorna l'sorting con le chiavi primarie

 $i = 0; foreach($items as $item) { // UPDATE item_table SET sorting = '$i' WHERE id = '$item'; i++; } 

Basta aggiungere un'altra colonna. Chiamalo order

Hai l'ordine delle righe e each row ha un ID o una chiave primaria. Basta scorrere le righe una alla volta e impostare l'ordine man mano che si procede. Così:

 UPDATE item_table SET order = 0 WHERE id="fred"; UPDATE item_table SET order = 1 WHERE id="larry"; UPDATE item_table SET order = 2 WHERE id="john"; UPDATE item_table SET order = 3 WHERE id="sydney"; 

Sono sicuro che ci sono modi complicati per farlo mathmente, ma a volte le risposte semplici sono le migliori.

Quindi, quando si effettua una query, aggiungere SORT BY order .