Quiero almacenar horas en una tabla de base de datos, pero solo necesito almacenar horas y minutos. Sé que podría usar DATETIME e ignorar los otros componentes de la fecha, pero ¿cuál es la mejor manera de hacer esto sin almacenar más información de la que realmente necesito?
sql-server
database
database-design
datetime
Matthew Dresser
fuente
fuente
Respuestas:
Puede almacenarlo como un número entero del número de minutos después de la medianoche:
p.ej.
Sin embargo, necesitaría escribir algún código para reconstituir el tiempo, pero eso no debería ser complicado.
fuente
Si está utilizando SQL Server 2008+, considere el
TIME
tipo de datos. Artículo de SQLTeam con más ejemplos de uso.fuente
Le imploro que use dos valores DATETIME en su lugar, etiquetados como event_start y event_end .
El tiempo es un asunto complejo
La mayor parte del mundo ha adoptado ahora el sistema métrico basado en denery para la mayoría de las mediciones, con razón o sin ella. Esto es bueno en general, porque al menos todos podemos estar de acuerdo en que ag, es un ml, es un cm cúbico. Al menos aproximadamente así. El sistema métrico tiene muchas fallas, pero al menos tiene fallas consistentes a nivel internacional.
Sin embargo, con el tiempo tenemos; 1000 milisegundos en un segundo, 60 segundos a un minuto, 60 minutos a una hora, 12 horas por cada medio día, aproximadamente 30 días por mes que varían según el mes e incluso el año en cuestión, cada país tiene su diferencia horaria de los demás , la forma en que se formatea la hora en cada país varía.
Es mucho para digerir, pero en resumen, es imposible que un escenario tan complejo tenga una solución simple.
Se pueden cortar algunas esquinas, pero hay aquellas en las que es más prudente no
Aunque la respuesta principal aquí sugiere que almacenar un número entero de minutos después de la medianoche puede parecer perfectamente razonable, he aprendido a evitar hacerlo de la manera difícil.
Las razones para implementar dos valores DATETIME son un aumento en la precisión, resolución y retroalimentación.
Todos estos son muy útiles cuando el diseño produce resultados no deseados.
¿Estoy almacenando más datos de los necesarios?
Al principio, puede parecer que se está almacenando más información de la que necesito, pero hay una buena razón para recibir este golpe.
Almacenar esta información adicional casi siempre termina ahorrándome tiempo y esfuerzo a largo plazo, porque inevitablemente encuentro que cuando a alguien se le dice cuánto tiempo tomó algo, también querrá saber cuándo y dónde tuvo lugar el evento.
Es un planeta enorme
En el pasado, he sido culpable de ignorar que hay otros países en este planeta además del mío. Parecía una buena idea en ese momento, pero esto SIEMPRE ha provocado problemas, dolores de cabeza y una pérdida de tiempo más adelante. SIEMPRE considere todas las zonas horarias.
C#
Un DateTime se representa muy bien en una cadena en C #. El método ToString (formato de cadena) es compacto y fácil de leer.
P.ej
Servidor SQL
Además, si está leyendo su base de datos por separado de la interfaz de su aplicación, entonces dateTimes es agradable de leer de un vistazo y realizar cálculos en ellos es sencillo.
P.ej
Estándar de fecha ISO8601
Si usa SQLite, entonces no tiene esto, así que use un campo de texto y guárdelo en formato ISO8601, por ejemplo.
"2013-01-27T12: 30: 00 + 0000"
Notas:
Esto usa un reloj de 24 horas *
La parte de la compensación de tiempo (o +0000) de ISO8601 se asigna directamente al valor de longitud de una coordenada de GPS (sin tener en cuenta el horario de verano ni en todo el país).
P.ej
... donde ± se refiere a la dirección este u oeste.
Por lo tanto, vale la pena considerar si valdría la pena almacenar la longitud, latitud y altitud junto con los datos. Esto variará según la aplicación.
ISO8601 es un formato internacional.
La wiki es muy buena para obtener más detalles en http://en.wikipedia.org/wiki/ISO_8601 .
La fecha y la hora se almacenan en hora internacional y la compensación se registra según el lugar del mundo en que se almacenó la hora.
En mi experiencia, siempre existe la necesidad de almacenar la fecha y la hora completas, independientemente de si creo que existe cuando comienzo el proyecto. ISO8601 es una forma muy buena y preparada para el futuro de hacerlo.
Asesoramiento adicional gratis
También vale la pena agrupar los eventos como una cadena. Por ejemplo, si se graba una carrera, todo el evento podría agruparse por corredor, circuito de carrera, puntos de control de circuito y vueltas de circuito.
En mi experiencia, también es aconsejable identificar quién almacenó el registro. Ya sea como una tabla separada que se completa mediante un activador o como una columna adicional dentro de la tabla original.
Cuanto más pones, más sales
Entiendo completamente el deseo de ser lo más económico posible con el espacio, pero rara vez lo haría a costa de perder información.
Una regla empírica con las bases de datos es, como dice el título, una base de datos solo puede decirle lo que tiene de datos, y puede ser muy costoso revisar los datos históricos, llenando los vacíos.
La solución es hacerlo bien a la primera. Ciertamente, es más fácil decirlo que hacerlo, pero ahora debería tener una visión más profunda del diseño eficaz de la base de datos y, posteriormente, tener una oportunidad mucho mayor de hacerlo bien la primera vez.
Cuanto mejor sea su diseño inicial, menos costosas serán las reparaciones más adelante.
Solo digo todo esto, porque si pudiera retroceder en el tiempo, es lo que me diría cuando llegué allí.
fuente
Simplemente almacene una fecha y hora regular e ignore todo lo demás. ¿Por qué dedicar más tiempo a escribir código que carga un int, lo manipula y lo convierte en una fecha y hora, cuando podría simplemente cargar una fecha y hora?
fuente
DATETIME
tipo de datos tarda 4 bytes en almacenarse, mientras que,SMALLINT
por ejemplo, solo ocupa una cuarta parte. No hay gran diferencia si solo tiene unos pocos miles de filas, pero si tiene muchos millones de filas como lo hacen muchas empresas, el ahorro de espacio será sustancial.como no lo mencionó, si está en SQL Server 2008, puede usar el tipo de datos de tiempo; de lo contrario, use minutos desde la medianoche
fuente
SQL Server en realidad almacena el tiempo como fracciones de un día. Por ejemplo, 1 día completo = valor de 1. 12 horas es un valor de 0.5.
Si desea almacenar el valor de la hora sin utilizar un tipo DATETIME, almacenar la hora en forma decimal se adaptaría a esa necesidad, al mismo tiempo que simplifica la conversión a DATETIME.
Por ejemplo:
Almacenar el valor como DECIMAL (9,9) consumiría 5 bytes. Sin embargo, si la precisión no es de suma importancia, un REAL consumiría solo 4 bytes. En cualquier caso, el cálculo agregado (es decir, el tiempo medio) se puede calcular fácilmente en valores numéricos, pero no en tipos de datos / tiempo.
fuente
Los convertiría en un número entero (HH * 3600 + MM * 60) y los almacenaría de esa manera. Tamaño de almacenamiento pequeño y todavía bastante fácil de trabajar.
fuente
Si está utilizando MySQL, use un tipo de campo de TIME y la funcionalidad asociada que viene con TIME.
00:00:00 es el formato de hora estándar de Unix.
Si alguna vez tiene que mirar hacia atrás y revisar las tablas a mano, los números enteros pueden ser más confusos que una marca de tiempo real.
fuente
Prueba smalldatetime. Puede que no le brinde lo que desea, pero lo ayudará en sus necesidades futuras en manipulaciones de fecha / hora.
fuente
¿Estás seguro de que solo necesitarás las horas y los minutos? Si desea hacer algo significativo con él (como, por ejemplo, calcular lapsos de tiempo entre dos de esos puntos de datos), no tener información sobre las zonas horarias y el horario de verano puede dar resultados incorrectos. Es posible que las zonas horarias no se apliquen en su caso, pero el horario de verano sin duda lo hará.
fuente
En lugar de minutos después de la medianoche, lo almacenamos como reloj de 24 horas, como SMALLINT.
09:12 = 912 14:15 = 1415
al convertir de nuevo a "formato legible por humanos", simplemente insertamos dos puntos ":" dos caracteres de la derecha. Botón izquierdo con ceros si es necesario. Guarda las matemáticas en todos los sentidos y utiliza unos pocos bytes menos (en comparación con varchar), además de que obliga a que el valor sea numérico (en lugar de alfanumérico)
Aunque bastante tonto ... debería haber habido un tipo de datos TIME en MS SQL durante muchos años ya en mi humilde opinión ...
fuente
Lo que creo que está pidiendo es una variable que almacenará los minutos como un número. Esto se puede hacer con los diferentes tipos de variables enteras:
Luego, en su programa, simplemente puede ver esto en la forma que desee calculando:
Surge un problema cuando solicita que se utilice la eficiencia. Pero, si tienes poco tiempo, simplemente use un BigInt anulable para almacenar su valor de minutos.
Un valor de nulo significa que la hora aún no se ha registrado.
Ahora, lo explicaré en forma de un viaje de ida y vuelta al espacio exterior.
Desafortunadamente, una columna de tabla solo almacenará un tipo. Por lo tanto, deberá crear una nueva tabla para cada tipo según sea necesario.
Por ejemplo:
Si MinutesInput = 0 .. 255 entonces use TinyInt (Convertir como se describe arriba).
Si MinutesInput = 256 .. 131071 , utilice SmallInt (Nota: el valor mínimo de SmallInt es -32,768. Por lo tanto, niegue y agregue 32768 cuando almacene y recupere el valor para utilizar el rango completo antes de convertir como se indicó anteriormente).
Si MinutesInput = 131072 .. 8589934591 , utilice Int (Nota: niegue y agregue 2147483648 según sea necesario).
Si MinutesInput = 8589934592 .. 36893488147419103231 , utilice BigInt (Nota: agregue y niegue 9223372036854775808 según sea necesario).
Si MinutesInput > 36893488147419103231 , personalmente usaría VARCHAR (X) aumentando X según sea necesario, ya que un carácter es un byte. Tendré que volver a visitar esta respuesta en una fecha posterior para describir esto en su totalidad (o tal vez un compañero stackoverflowee pueda terminar esta respuesta).
Dado que cada valor sin duda requerirá una clave única, la eficiencia de la base de datos solo será aparente si el rango de los valores almacenados es una buena combinación entre muy pequeño (cerca de 0 minutos) y muy alto (mayor que 8589934591).
Hasta que los valores que se almacenan realmente alcancen un número mayor que 36893488147419103231, entonces también podría tener una sola columna BigInt para representar sus minutos, ya que no necesitará desperdiciar un Int en un identificador único y otro int para almacenar el valor de los minutos.
fuente
El ahorro de tiempo en formato UTC puede ayudar mejor, como sugirió Kristen.
Asegúrese de que está utilizando un reloj de 24 horas porque no hay meridianos AM o PM en UTC.
Ejemplo:
Sigue siendo preferible utilizar el formato estándar de cuatro dígitos.
fuente
Almacene
ticks
como unlong
/bigint
, que actualmente se mide en milisegundos. El valor actualizado se puede encontrar mirando elTimeSpan.TicksPerSecond
valor.La mayoría de las bases de datos tienen un tipo DateTime que almacena automáticamente la hora como tics entre bastidores, pero en el caso de algunas bases de datos, como SqlLite, almacenar ticks puede ser una forma de almacenar la fecha.
La mayoría de los idiomas permiten la conversión fácil de
Ticks
→TimeSpan
→Ticks
.Ejemplo
En C # el código sería:
Sin embargo, tenga en cuenta, porque en el caso de SqlLite, que solo ofrece una pequeña cantidad de tipos diferentes, que son;
INT
,REAL
yVARCHAR
será necesario almacenar el número de ticks como una cadena o dosINT
celdas combinadas. Esto es porque unINT
es un número con signo de 32 bits, mientras queBIGINT
es un número con signo de 64 bits.Nota
Sin embargo, mi preferencia personal sería almacenar la fecha y la hora como una
ISO8601
cadena.fuente
En mi humilde opinión, cuál es la mejor solución depende en cierta medida de cómo almacena el tiempo en el resto de la base de datos (y el resto de su aplicación)
Personalmente, he trabajado con SQLite y trato de usar siempre marcas de tiempo Unix para almacenar el tiempo absoluto, por lo que cuando trato con la hora del día (como usted pregunta) hago lo que Glen Solsberry escribe en su respuesta y almaceno la cantidad de segundos desde la medianoche.
Al adoptar este enfoque general, las personas (¡incluyéndome a mí!) Que leen el código se confunden menos si uso el mismo estándar en todas partes.
fuente