2012-12-22 6 views
7

Quindi ho una domanda interessante che non sono sicuro sia considerata un 'trucco' o meno. Ho esaminato alcune domande ma non ho trovato un duplicato, quindi eccolo qui. Fondamentalmente, ho bisogno di sapere se questo è inaffidabile o considerato una cattiva pratica.Pratica SQL discutibile - Ordina per id anziché tempo di creazione

Ho una tabella molto semplice con un ID di incremento automatico univoco e un timestamp created_at. (versione semplificata del mio problema a chiarire il concetto in questione)

+-----------+--------------------+ 
| id  |created_at   | 
+-----------+--------------------+ 
| 1   |2012-12-11 20:35:19 | 
| 2   |2012-12-12 20:35:19 | 
| 3   |2012-12-13 20:35:19 | 
| 4   |2012-12-14 20:35:19 | 
+-----------+--------------------+ 

Entrambe queste colonne sono aggiunti dinamicamente in modo si può dire che un nuovo 'inserto' sarà SEMPRE avere una maggiore id e SEMPRE hanno una data più grande.

OBIETTIVO - molto semplicemente prendere i risultati in ordine di created_at per

soluzione one decrescente - Una query che gli ordini per data in ordine

SELECT * FROM tablename 
ORDER BY created_at DESC 

soluzione dei due decrescente - Una query che ordina per ID in ordine decrescente

SELECT * FROM tablename 
ORDER BY id DESC 

La soluzione due è considerata una cattiva pratica? O la soluzione due è il modo corretto di fare le cose. Qualsiasi spiegazione dei tuoi ragionamenti sarebbe molto utile mentre sto cercando di capire il concetto, non solo di ottenere una risposta. Grazie in anticipo.

+0

Bene, l'ordinamento per ID può e trarrà vantaggio dall'indicizzazione. Dovresti includere parti rilevanti del tuo schema nella domanda. – Perception

+0

Anche se non so se c'è un "modo ufficiale" per farlo, la query "ordina per" esiste per fare proprio questo. Per ordinare da una colonna. L'unico inconveniente che vedo è che il timestamp può avere duplicati (due inserti nello stesso secondo) E che la query potrebbe essere più lenta, a causa di un indice mancante. – ATaylor

risposta

6

Nella pratica tipica si può quasi sempre presumere che un ID autoincrement possa essere ordinato per fornire i record nell'ordine di creazione (in entrambe le direzioni). Tuttavia, si dovrebbe notare che questo non è considerato portatile in termini di dati. È possibile spostare i dati su un altro sistema in cui vengono ricreate le chiavi, ma i dati created_at sono gli stessi.

In realtà c'è un bel StackOverflow discussion di questo problema.

Il riepilogo di base è la prima soluzione, l'ordinamento di created_at è considerata la migliore pratica. Assicurati, tuttavia, di indicizzare correttamente il campo created_at per ottenere le migliori prestazioni.

+0

Grazie per il link alla discussione, deve averlo perso nella mia ricerca –

+2

+1 per considerare cosa può succedere ai dati in seguito. – Javier

+0

Perché il downvote? – davidethell

4

Ci sono un paio di differenze tra le due opzioni.


Il primo è che possono dare risultati diversi.

Il valore di created_at potrebbe essere influenzato dal momento della regolazione sul server ma la colonna id non sarà interessata. Se il tempo viene regolato all'indietro (manualmente o automaticamente dal software di sincronizzazione dell'ora), è possibile ottenere i record inseriti successivamente ma con i timestamp che precedono i record inseriti in precedenza. In questo caso otterrai un ordine diverso a seconda della colonna che ordini. L'ordine che consideri "corretto" spetta a te.


Il secondo è la prestazione. È probabile che sia più veloce a ORDER BY il tuo clustered index.

Come l'indice cluster accelera query

Accesso fila attraverso l'indice cluster è veloce perché i dati riga è sulla stessa pagina in cui la ricerca indice di porta.

Per impostazione predefinita, la chiave in cluster è la chiave primaria, che nel tuo caso è presumibilmente la colonna id. Probabilmente troverai che ORDER BY id è leggermente più veloce di ORDER BY created_at.

+0

MySQL non si preoccupa degli indici cluster. Non è probabile che le tabelle InnoDB memorizzino i record nell'ordine di creazione. – Javier

+0

@ Javier: Grazie per il tuo commento. Ho aggiunto un collegamento alla documentazione sugli indici cluster e citato dalla documentazione. –

+0

ronzio ... sto in piedi corretto. devono essersi infiltrati nell'implementazione di InnoDB mentre non stavo guardando. – Javier

3

Le chiavi primarie, in particolare di tipo surrogato, di solito non rappresentano alcun tipo di dati significativi a parte il fatto che la loro semplice funzione è quella di consentire registrazioni univocamente identificabili. Poiché le date in questo caso rappresentano dati significativi che hanno significato al di fuori della sua funzione primaria, direi che l'ordinamento in base alle date è un approccio più logico qui.

3

Ordinamento per ordini con inserimento ordine.

Se si dispone di casi di utilizzo in cui è possibile ritardare l'inserimento, ad esempio un processo batch, è necessario effettuare l'ordine in base a created_at per ordinare in base al tempo.

Entrambi sono accettabili se soddisfano le tue esigenze.

5

Non si deve fare affidamento sull'ID per qualcosa di diverso da quello che identifica univocamente una riga. È un numero arbitrario che corrisponde solo all'ordine in cui sono stati creati i record.

Diciamo che avete questa tabella

ID creation_date 
1 2010-10-25 
2 2010-10-26 
3 2012-03-05 

In questo caso, l'ordinamento su ID invece di opere creation_date.

Ora in futuro ti rendi conto, oh, whoops, devi modificare la data di creazione dell'ID record n. 2 al 2010-09-17. I suoi tipi utilizzando l'ID ora riportare i record nello stesso ordine:

1 2010-10-25 
2 2010-09-17 
3 2012-03-05 

anche se con la nuova data dovrebbero essere:

2 2010-09-17 
1 2010-10-25 
3 2012-03-05 

Versione corta: colonne di utilizzare i dati per lo scopo che erano creato. Non fare affidamento sugli effetti collaterali dei dati.