2009-01-31 14 views
20

Supponiamo di avere alcuni oggetti e voglio che l'utente sia in grado di riordinarli in qualsiasi modo desiderino, ad esempio, trascinandoli. Così avreiCome salvare un particolare "ordine" mutevole in un database

  • formaggio
  • muffin
  • latte

e quindi l'utente trascina 'latte' verso l'alto, rendendo il nuovo ordine

  • latte
  • formaggio
  • muffin

Esiste una best practice su come memorizzare l'ordine di questi oggetti in un database? L'approccio ingenuo sarebbe probabilmente quello di archiviare un valore numerico chiamato "ordine" per ogni oggetto, ma questo mi sembra troppo complicato, perché dovresti mischiare i valori dell'ordine per la maggior parte del tempo.

+1

Duplicato di http://stackoverflow.com/questions/495390/orm-or-sualcosa-per-mangiare-sql-tables-with-an-order-column- efficientemente – cletus

risposta

11

L'approccio "ingenuo" che suggerisci è anche la migliore pratica!

2

Se si desidera visualizzarli nuovamente nello stesso ordine E si desidera poterli riordinare in qualsiasi momento, non penso che si possa evitare di memorizzare un valore che indica la priorità di visualizzazione nel database. Ho utilizzato l'approccio che descrivi per ordinare gli articoli in una FAQ, i ricercatori associati a una sovvenzione, l'ordine degli articoli in un menu, ...

12

Prendendo in considerazione la risposta di Tony Andrews, potresti in alternativa memorizzare un indice "successivo" con ogni voce. Quindi, quando li tiri tutti dentro, cammina nell'array seguendo la catena. Ciò rende più semplice lo spostamento di un oggetto, poiché è sufficiente toccare solo due righe al massimo.

Lo svantaggio di questo approccio è che se è necessario un sottoinsieme (ad esempio i primi 3 elementi) è ancora necessario inserire tutti gli elementi o utilizzare un ciclo SQL. Quindi è tra l'influenza su tutte le righe durante l'aggiornamento, o l'accesso a tutti gli elementi durante la lettura. Come sempre, misura la velocità e vedi quale è meglio per la tua situazione.

2

Sì, in un database relazionale non esiste un ordine, è uno dei concetti fondamentali. Quindi non c'è modo senza un valore numerico o qualcosa del genere.

5

Guardando Tony Andrew e le risposte di Mark, in particolare, a quanto pare ho davvero solo due alternative:

  • Salvataggio di un valore 'prossimo', rendendo gli oggetti si comportano come una lista collegata (vedi risposta di Mark)
    Con questo, cambiare l'ordine è economico, ma dovrei recuperare gli articoli e quindi ordinarli in base al loro valore 'successivo', che è costoso
  • Salvare un valore 'ordine' (vedere la risposta di Tony Andrew)
    Ciò rende il recupero economico ma il salvataggio di un nuovo orde r potenzialmente costoso, perché nel caso peggiore dovrei cambiare tutti i valori dell'ordine. il cletus sottolinea che si potrebbe usare un numero elevato sotto forma di 2^n per il moltiplicatore dell'ordine.

Meta: Tutte queste risposte sono buone e corrette, che uno deve scegliere come corrette?

+0

Dato che hai chiesto di archiviare in un DB, voterei per l'approccio "ingenuo" .. inserendo originariamente gli oggetti con un offset di, ad esempio 100, potresti minimizzare la collisione di riordino (quando avresti avuto per cambiare più di un oggetto da reinserire in una nuova posizione) – lexu

+3

Nessuno dei due è assolutamente "migliore" al 100%. Se hai molto più letture che scritture, la velocità di recupero è probabilmente la preoccupazione principale. Se hai molte scritture o devi ordinare un numero elevato di articoli, la velocità di scrittura è importante. È un giudizio caso per caso. – Tadmas

3

Nelle mie applicazioni le operazioni di lettura stanno per accadere molto più frequentemente rispetto alle scritture. Vai con il valore numerico per indicare l'ordinamento e gestire il costo del riordino degli articoli. Questo è più che compensato dal fatto che è possibile recuperare in modo efficiente gli articoli nell'ordine corretto per scopi di visualizzazione (che in un'applicazione tipica avviene più frequentemente di quanto non faccia il ricorso).

Inoltre, come già accennato, se si recupera un sottoinsieme di dati (filtro su tipo o qualcosa) gli articoli rimanenti sono ancora nell'ordine corretto.

Ricordare il mantra K.I.S.S.

14

Il modo migliore che ho trovato per gestire questo è quello di avere un campo ordine in virgola mobile. Quando sposti qualcosa tra altri due oggetti, imposta quel campo a metà strada tra i suoi vicini.

Questo è economico su entrambe le letture e le scritture. L'unico lato negativo è che i galleggianti continuano ad allungarsi :)

+1

+1 per il tipo di dati in virgola mobile. Se imposti i valori di ordine iniziale in modo che siano sfalsati di 100 e utilizzi i float, puoi evitare cifre decimali gigantesche e avere comunque il vantaggio di non dover mai regolare un tipo di dati di ricerca per una collisione. – aviemet

Problemi correlati