2009-02-04 13 views
10

¿Cuál es la mejor/más eficiente manera de almacenar fechas antiguas (anteriores a 1753) en SQL Server 2005? No me preocupa almacenar tiempos, solo fechas. El tipo de datos datetime de SQL Server solo puede contener fechas del 1 de enero de 1753. La documentación de MSDN indica que hay tipos de datos date y datetime2, pero SQL Server Management Studio no parece ser compatible (Error: tipo de datos no válido).La mejor manera de almacenar fechas antiguas en SQL Server

¿Qué tan ineficiente sería almacenar fechas como cadenas o entradas de la forma "AAAAMMDD"? Hago muchas consultas y clasifico en dos campos de fecha en mi tabla (StartDate y EndDate).

ACTUALIZACIÓN:

Ha habido algunas sugerencias a continuación a la tienda de año, mes y día en campos separados. ¿Cuál es el beneficio de almacenar las piezas en diferentes campos en lugar de en un único campo entero?

+0

Usar 3 enteros en lugar de 1 tiene la ventaja de que no necesita calcular el número de días, como lo propone CodeMonkey1 . Eso es más difícil de lo que parece. – Treb

+0

¿Con qué se relacionan las fechas? Es posible que [tenga que considerar los problemas Gregoriano vs Calendario Juliano] (http://stackoverflow.com/questions/3310569/what-is-the-significance-of-1-1-1753-in-sql-server/3310588#3310588) –

Respuesta

15

El tipo date es definitivamente lo que quieres usar. Su rango es "1 de enero, 1 d. De A. hasta el 31 de diciembre de 9999 d. También almacena información de fecha, sin la parte de tiempo.

¿Está usted, tal vez, utilizando SSMS 2005, en lugar de 2008, o conectado a una instancia de 2005? Ese tipo era introduced in SQL Server 2008. Si tiene la capacidad de utilizar una base de datos de 2008, creo que es indudablemente el camino a seguir.

+0

¡parece una razón para actualizar! – inspite

4

Nunca he hecho esto, pero tal vez podría almacenar la fecha como un número entero que representa el número de días desde la fecha mínima que le convenga. Luego, puede crear una tabla de búsqueda que correlacione esos enteros con un año, mes y día, o puede escribir funciones definidas por el usuario para convertir de un número entero a una fecha o viceversa.

Eso debería ser bastante eficiente en términos de selección y clasificación.

4

Las cadenas probablemente serían menos eficientes que simplemente almacenar enteros para el año, el mes y el día. Eso es un poco más verborrea en sus consultas, pero es probable que funcionen más rápido, ya que puede indexarlos de manera que tengan sentido para los tipos de consultas que está haciendo.

Así, por ejemplo:

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

Entonces consultas serían todos como:

-- 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) 

Eso es feo, para estar seguro, pero eso es tan feo como se hace para consultas de rango, por lo una vez que lo escribe la primera vez, puede encapsularlo en una función.

1

Un problema con el almacenamiento de fechas en el formato AAAAMMDD es que puede terminar con fechas que no existen (por ejemplo, 16000231 - el 31 de febrero no existe). Debería hacer un lado del cliente de validación, antes de ingresarlo en el archivo db.

Lo mismo vale para guardar la fecha en enteros de año, mes y día, según lo propuesto por Ian Varley. Pero aparte de eso me gusta su respuesta y me gustaría haberlo pensado ;-)

+0

¿Qué hace cada cliente adecuado para los datos que recibe de cualquier fuente externa? :) (pista: lo valida) – Esko

+0

Yup. Es solo algo que puede pasarse por alto cuando se trata de fechas, porque los tipos de fecha incorporados hacen la validación por usted. – Treb

1

YYYYMMDD = 8 bytes. Puede cortarlo a 4 bytes con SMALLINT y TINYINT usando 3 columnas.

1

Parece una buena idea usar las palabras sugeridas por CodeMonkey1, y facilitará la "fecha matemática" (por ejemplo, alguna fecha + XX días).

Escribe algunos UDF (también según lo aconsejado por CodeMonkey1) para convertir int -> AAAAMMDD -> int y usted tendrá la flexibilidad que Ian Varley menciona en su respuesta.

1

Una idea: si tiene algún conocimiento de .NET podría crear un tipo de CLR para almacenar la fecha, que esencialmente sería una fecha y hora. Si está haciendo muchos cálculos con la fecha en lugar de simples consultas, podría ser algo para investigar

Cuestiones relacionadas