2011-01-21 19 views
21

abbiamo avuto questa discussione di programmazione su Freenode e questa domanda si è presentata quando stavo cercando di utilizzare un VARCHAR (255) per memorizzare una variabile di data in questo formato: D/MM/YYYY. Quindi la domanda è perché è così brutto usare VARCHAR per memorizzare la data. Ecco i vantaggi:Quando utilizzare VARCHAR e DATE/DATETIME

  1. È più veloce da codificare. In precedenza ho usato DATE, ma la formattazione delle date era un vero problema.
  2. Più energia ha bisogno di utilizzare la stringa rispetto a Data? A chi importa, viviamo nell'era Ghz.
  3. La sua non è eticamente corretto (lolwut?) Questo è ciò che l'altro utente mi ha detto ...

Allora, cosa si preferisce utilizzare per memorizzare una data? SQL VARCHAR o SQL DATE?

+2

Una domanda per stackoverflow.com penso che gli abbonati: –

+1

: aiuterà l'interrogante se lasci un motivo * perché * non ti piace la domanda. – Kramii

+2

Il fatto che le risposte possano sembrare ovvie ai programmatori esperti e che il tono fosse rant-ish non ne fanno una domanda meno completamente legittima. Inoltre, ha generato buone risposte informative. Votato perché non meritava un punteggio negativo. – cbrandolino

risposta

11

Quando avrete database con più di 2-3 milioni di righe saprete perché è meglio usare DATETIME di VARCHAR :)

semplice risposta è che con i database - la potenza di elaborazione non è un problema più. Solo la dimensione del database è dovuta al tempo di ricerca dell'HDD.

In sostanza con hard disk moderni si può leggere circa 100 record/secondo quelli letti in ordine casuale (di solito il caso) quindi è necessario fare tutto il possibile per ridurre la dimensione DB, perché:

  • Il teste di HDD non dovranno "viaggiare" questo molto
  • potrai inserire più dati nella RAM

alla fine è sempre HDD tempi di ricerca, che ti ucciderà. Per esempio. qualche semplice query GROUP BY con molte righe potrebbe richiedere un paio d'ore quando viene eseguita su disco rispetto a un paio di secondi quando viene eseguita in RAM => a causa dei tempi di ricerca.

Per VARCHAR's non è possibile effettuare ricerche. Se odi il modo in cui SQL gestisce così tanto le date, usa semplicemente timestamp di unix nel campo intero a 32 bit. Avrai (fondamentalmente) tutti i vantaggi dell'utilizzo del campo SQL DATE, dovrai solo manipolare e formattare le date usando il tuo linguaggio di programmazione scelto, non le funzioni SQL.

+2

Naturalmente, se lo stai memorizzando in un campo intero a 32 bit, devi anche essere a conoscenza del [problema dell'anno 2038] (https://en.wikipedia.org/wiki/Year_2038_problem). – Powerlord

+0

Grazie per l'idea di epoca, manipolare le date mi fa impazzire :) –

4

Due motivi:

  • ordina i risultati per le date
  • Insensibile alla formattazione data cambia

Quindi cerchiamo di prendere per esempio una serie di record che assomiglia a questo:

5/12/1999 | Frank N Stein 
1/22/2005 | Drake U. La 
10/4/1962 | Goul Friend 

Se dovessimo memorizzare i dati a modo vostro, ma ordinati in base alle date nell'assegnare o rder SQL risponderà con il gruppo di risultati che assomiglia a questo:

1/22/2005 | Drake U. La 
10/4/1962 | Goul Friend 
5/12/1999 | Frank N. Stein 

Dove se abbiamo memorizzato le date come un DATETIME, SQL risponderà correttamente ordinando loro in questo modo:

10/4/1962 | Goul Friend 
5/12/1999 | Frank N. Stein 
1/22/2005 | Drake U. La 

Inoltre, se da qualche parte verso il basso la strada che ti serviva per visualizzare le date in un formato diverso, ad esempio YYYY-MM-DD, allora dovresti trasformare tutti i tuoi dati o gestire contenuti misti. Quando viene archiviato come SQL DATE, sei costretto a trasformare la trasformazione in codice e molto probabilmente hai un punto in cui cambiare il formato per visualizzare tutte le date - gratuitamente.

+0

Vedere la mia risposta in merito alla norma ISO 8601 di seguito. –

34

Perché non inserire le viti con un martello?

Perché non è lo strumento giusto per il lavoro.

Alcuni degli svantaggi della versione VARCHAR:

  • Non si può facilmente aggiungere/togliere giorni alla versione VARCHAR.
  • È più difficile estrarre solo mese/anno.
  • Non c'è nulla che ti impedisce di inserire dati non datati nella colonna VARCHAR nel database.
  • La versione di VARCHAR è specifica per la cultura.
  • Non è possibile ordinare facilmente le date.
  • È difficile modificare il formato se si desidera in seguito.
  • Non è convenzionale, il che renderà più difficile la comprensione da parte di altri sviluppatori.
  • In molti ambienti, l'utilizzo di VARCHAR utilizzerà più spazio di archiviazione. Questo potrebbe non essere importante per piccole quantità di dati, ma in ambienti commerciali con milioni di righe di dati questo potrebbe fare una grande differenza.

Naturalmente, nei tuoi progetti di hobby puoi fare quello che vuoi. In un ambiente professionale insisterei nell'utilizzare lo strumento giusto per il lavoro.

+1

In realtà, le viti martellanti sono abbastanza utili a volte ... –

+4

I cacciaviti servono per estrarre le viti ... – Matt

+0

@ Dercsár: Infatti. E ci sono occasioni in cui anche mettere le date in un VARCAR è utile. Ma non è generalmente raccomandato. – Kramii

1

tra DATE/DATETIME e VARCHAR per le date vorrei andare con DATE/DATETIME ogni volta. Ma c'è una terza opzione trascurata. Memorizzandolo come INTEGER non firmato!

Ho deciso di andare con INTEGER unsigned nel mio ultimo progetto, e sono davvero soddisfatto di aver fatto quella scelta invece di archiviarlo come DATE/DATETIME. Perché stavo passando le date tra client e server ha reso il tipo ideale per me da usare. Invece di doverlo memorizzare come DATE e dover riconvertire ogni volta che seleziono, lo seleziono e lo uso comunque lo voglio. Se si desidera selezionare la data come data "leggibile", è possibile utilizzare la funzione FROM_UNIXTIME().

Anche un numero intero occupa 4 byte mentre DATETIME occupa 8 byte. Risparmio del 50% di spazio di archiviazione.

Il problema di ordinamento proposto da Berin viene risolto utilizzando il numero intero come memoria per le date.

+1

Si prega di notare che un tipo di dati datetime è un numero intero (due, in realtà): il più a sinistra è il numero di giorni dall'epoca, il più a destra è il numero di ticks millisecondi dall'inizio della giornata (00:00: 00.000). L'epoca (zero-point in calendar-speak) del calandar di SQL Server è il 1 gennaio 1900 00: 00: 00.000 — questo è il motivo per cui 'convert (datetime, '')' produce un valore datetime del 1 ° gennaio 1900. –

3

Preferirei utilizzare i tipi data/datetime, solo per semplicità/coerenza.

Se lo fai conservarlo come una stringa di caratteri, conservarla in ISO 8601 formato:

Tra le altre cose, ISO 8601 data/ora la stringa (A) collaziona correttamente, (B) sono leggibili dall'uomo, (C) sono indipendenti dalla locale e (D) sono facilmente convertibili in altri formati. Per presepe dalla fascetta ISO, ISO 8601 stringhe offrono

rappresentazioni per i seguenti:

  • Data
  • Tempo del giorno
  • Coordinated Universal Time (UTC)
  • ora locale con offset a UTC
  • Data e ora
  • Intervalli di tempo
  • intervalli di tempo ricorrenti

rappresentazioni possono essere in uno dei due formati: un formato di base che ha un numero minimo di caratteri e un formato esteso che aggiunge caratteri per migliorare la leggibilità umana. Ad esempio, il 3 gennaio 2003 può essere rappresentato come 20030103 o 2003-01-03.

[e]

offrono i seguenti vantaggi rispetto molti dei locali utilizzati rappresentazioni:

  • facilmente leggibili e scrivibili da sistemi
  • facilmente comparabili e ordinabili
  • Lingua indipendenti
  • Le unità più grandi sono scritte davanti alle unità più piccole
  • Per la maggior parte le rappresentazioni la notazione è breve e di lunghezza costante

Un'ultima cosa: se tutto quello che dovete fare è memorizzare una data, quindi riporlo nella ISO 8601 forma abbreviata AAAAMMGG in un char (8) colonna non richiede più spazio di archiviazione di un valore datetime (e non è necessario preoccuparsi del divario di 3 millisecondi tra l'ultimo tick del primo giorno e il primo tick del successivo. Ma questa è una questione per un'altra discussione. Se lo suddividi in 3 colonne — YYYY char(4), MM char(2), DD char(2), utilizzerai la stessa quantità di spazio di archiviazione e otterrai più opzioni per l'indicizzazione. Ancora meglio, archivia i campi come abbreviazione di yyyy (4 byte) e un minuscolo per ciascuno di MM e DD — ora sei giù a 6 byte per la data. Lo svantaggio, ovviamente, nella scomposizione dei componenti della data nelle loro parti costitutive è che la conversione in appropriati tipi di dati data/ora è complicata.

Problemi correlati