2009-02-04 16 views
10

Qual è il modo migliore/più efficace per archiviare le date precedenti (pre-1753) in SQL Server 2005? Non mi preoccupo dei tempi di archiviazione, solo delle date. Il tipo di dati datetime di SQL Server può contenere solo le date del 1 ° gennaio 1753. La documentazione MSDN indica che esistono tipi di dati data e datetime2, ma SQL Server Management Studio non sembra supportarli (Errore: tipo di dati non valido).Il modo migliore per archiviare le vecchie date in SQL Server

Quanto sarebbe inefficiente memorizzare le date come stringhe o interi del formato "AAAAMMGG"? Faccio molte ricerche e ordinamenti su due campi data nella mia tabella (StartDate e EndDate).

UPDATE:

Ci sono stati in campi separati alcuni suggerimenti di seguito per memorizzare l'anno, il mese e la data. Qual è il vantaggio di archiviare le parti in campi diversi anziché in un singolo campo intero?

+0

Utilizzare 3 interi invece di 1 ha il vantaggio che non è necessario calcolare il numero di giorni, come proposto da CodeMonkey1 . È più difficile di quanto sembri. – Treb

+0

A cosa si riferiscono le date? Potresti [prendere in considerazione i problemi di Gregorian vs Calendar di Julian] (http://stackoverflow.com/questions/3310569/questo-è-il-distanza-di-1-1-1753-in-sql-server/3310588#3310588) –

risposta

15

Il tipo date è sicuramente quello che si desidera utilizzare. La sua portata è "1 ° gennaio 1 ° D fino al 31 dicembre 9999 A.D." Inoltre memorizza solo le informazioni sulla data, senza la parte relativa all'ora.

Stai forse utilizzando SSMS 2005 anziché 2008 o connesso a un'istanza del 2005? Quel tipo era introduced in SQL Server 2008. Se hai la possibilità di utilizzare un database 2008, penserei che sia indiscutibilmente la strada da percorrere.

+0

sembra un motivo per aggiornare! – inspite

4

Non l'ho mai fatto, ma forse è possibile memorizzare la data come numero intero che rappresenta il numero di giorni da quando qualsiasi data minima si adatta a te. Quindi è possibile creare una tabella di ricerca che associ tali numeri interi a un anno, mese e giorno oppure è possibile scrivere funzioni definite dall'utente per convertire da un numero intero a una data o viceversa.

Questo dovrebbe essere abbastanza efficiente in termini di selezione e ordinamento.

4

Le stringhe sarebbero probabilmente meno efficienti rispetto alla semplice memorizzazione di numeri interi per anno, mese e giorno. È un po 'più verboso nelle tue query, ma probabilmente funzioneranno più velocemente in quanto puoi indicizzarle in modo ragionevole per il tipo di query che stai facendo.

Così, per esempio:

CREATE TABLE myOldDates (
    year INT, 
    month INT, 
    day INT, 
    -- otherstuff ... 
) 

Poi query sarebbero tutti essere come:

-- get records between 5/15/1752 and 3/19/1754 
SELECT * FROM myOldDates 
    WHERE 
    (year = 1752 AND ((month = 5 and day >= 15) or month > 5) OR year > 1752) 
    AND (year = 1754 AND ((month = 3 and day <= 19) or month < 3) OR year < 1754) 

Cioè brutto, per essere sicuri, ma questo è così brutto come si arriva per le query gamma, così una volta che lo scrivi la prima volta, puoi incapsularlo in una funzione.

1

Un problema con l'archiviazione delle date nel formato AAAAMMGG è che potresti finire con date che non esistono (ad esempio 16000231 - il 31 febbraio non esiste). Dovresti fare un po 'di client di validazione, prima di inserirlo nel db.

Lo stesso è di couse true per la memorizzazione della data in interi anno, mese e giorno, come proposto da Ian Varley. Ma aisde da questo mi piace la sua risposta e vorrei solo ci avrei pensato ;-)

+0

Cosa fa ogni client appropriato per i dati ricevuti da qualsiasi fonte esterna? :) (suggerimento: valida) – Esko

+0

Sì. La sua unica cosa che può essere trascurata quando si tratta di date, perché i tipi di data incorporati fanno la convalida per voi. – Treb

1

YYYYMMDD = 8 byte. È possibile ridurlo a 4 byte con SMALLINT e TINYINT utilizzando 3 colonne.

1

L'utilizzo di ints come suggerito da CodeMonkey1 sembra una buona idea e renderà più semplice eseguire "date math" (ad esempio, una data + XX giorni).

Scrivere alcuni UDF (anche secondo il consiglio del CodeMonkey1) per convertire int -> AAAAMMGG -> int e avrete la flessibilità che Ian Varley cita nella sua risposta.

1

Un'idea: se si dispone di alcune conoscenze .NET, è possibile creare un tipo CLR per archiviare la data, che sarebbe essenzialmente un datetime. Se stai facendo molti calcoli con la data piuttosto che con semplici query, potrebbe essere qualcosa da investigare

Problemi correlati