¿Recomendaría usar un campo de fecha y hora o una marca de tiempo , y por qué (usando MySQL)?
Estoy trabajando con PHP en el lado del servidor.
¿Recomendaría usar un campo de fecha y hora o una marca de tiempo , y por qué (usando MySQL)?
Estoy trabajando con PHP en el lado del servidor.
Respuestas:
Las marcas de tiempo en MySQL generalmente se usan para rastrear los cambios en los registros, y a menudo se actualizan cada vez que se cambia el registro. Si desea almacenar un valor específico, debe usar un campo de fecha y hora.
Si quería decir que desea decidir entre usar una marca de tiempo UNIX o un campo de fecha y hora nativo de MySQL, vaya con el formato nativo. Puede hacer cálculos dentro de MySQL de esa manera
("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")
y es simple cambiar el formato del valor a una marca de tiempo UNIX ("SELECT UNIX_TIMESTAMP(my_datetime)")
cuando consulta el registro si desea operarlo con PHP.
DATETIME
representa una fecha (como se encuentra en un calendario) y una hora (como se puede observar en un reloj de pared), mientras que TIMESTAMP
representa un punto en el tiempo bien definido. Esto podría ser muy importante si su aplicación maneja zonas horarias. ¿Hace cuánto fue '2010-09-01 16:31:00'? Depende de la zona horaria en la que te encuentres. Para mí fue hace solo unos segundos, para ti puede representar un momento en el futuro. Si digo 1283351460 segundos desde '1970-01-01 00:00:00 UTC', sabes exactamente de qué momento hablo. (Ver la excelente respuesta de Nir a continuación). [Desventaja: rango válido].
En MySQL 5 y superior, los valores de TIMESTAMP se convierten de la zona horaria actual a UTC para el almacenamiento, y se vuelven a convertir de UTC a la zona horaria actual para su recuperación. (Esto ocurre solo para el tipo de datos TIMESTAMP, y no para otros tipos como DATETIME).
Por defecto, la zona horaria actual para cada conexión es la hora del servidor. La zona horaria se puede establecer por conexión, como se describe en Soporte de zona horaria del servidor MySQL .
Siempre uso los campos DATETIME para cualquier cosa que no sean metadatos de fila (fecha de creación o modificación).
Como se menciona en la documentación de MySQL:
El tipo DATETIME se usa cuando necesita valores que contienen información de fecha y hora. MySQL recupera y muestra los valores DATETIME en formato 'AAAA-MM-DD HH: MM: SS'. El rango admitido es '1000-01-01 00:00:00' a '9999-12-31 23:59:59'.
...
El tipo de datos TIMESTAMP tiene un rango de '1970-01-01 00:00:01' UTC a '2038-01-09 03:14:07' UTC. Tiene diferentes propiedades, según la versión de MySQL y el modo SQL en el que se ejecuta el servidor.
Es muy probable que alcance el límite inferior de TIMESTAMP en uso general, por ejemplo, almacenar la fecha de nacimiento.
new Date().getTime()
ya le da un valor de 64 bits.
Los siguientes ejemplos muestran cómo el TIMESTAMP
tipo de fecha cambió los valores después de cambiar time-zone to 'america/new_york'
dónde no DATETIME
se modifica.
mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name | Value |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone | Asia/Calcutta |
+------------------+---------------------+
mysql> create table datedemo(
-> mydatetime datetime,
-> mytimestamp timestamp
-> );
mysql> insert into datedemo values ((now()),(now()));
mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime | mytimestamp |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+
mysql> set time_zone="america/new_york";
mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime | mytimestamp |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+
He convertido mi respuesta en un artículo para que más personas puedan encontrar esto útil, MySQL: Tipos de datos de fecha y hora y fecha y hora .
DATETIME
tiempo efectivo cambió con el cambio de zona horaria, TIMESTAMP
no cambió, pero la representación humana sí.
set time_zone="america/new_york"
;
La principal diferencia es que DATETIME es constante, mientras que TIMESTAMP se ve afectado por la time_zone
configuración.
Por lo tanto, solo es importante cuando tiene, o puede tener en el futuro, clústeres sincronizados en diferentes zonas horarias.
En palabras más simples: si tengo una base de datos en Australia, y tomo un volcado de esa base de datos para sincronizar / llenar una base de datos en América, entonces TIMESTAMP se actualizará para reflejar el tiempo real del evento en la nueva zona horaria, mientras que DATETIME todavía reflejan la hora del evento en la zona horaria au .
Un gran ejemplo de DATETIME utilizado donde TIMESTAMP debería haberse utilizado es en Facebook, donde sus servidores nunca están seguros de qué hora sucedió en las zonas horarias. Una vez que tuve una conversación en la que el tiempo decía que estaba respondiendo a los mensajes antes de que el mensaje se enviara realmente. (Esto, por supuesto, también podría haber sido causado por una mala traducción de la zona horaria en el software de mensajería si las horas se publicaron en lugar de sincronizarse).
Tomo esta decisión sobre una base semántica.
Uso una marca de tiempo cuando necesito grabar un punto fijo en el tiempo (más o menos). Por ejemplo, cuando se insertó un registro en la base de datos o cuando tuvo lugar alguna acción del usuario.
Utilizo un campo de fecha y hora cuando la fecha / hora se puede configurar y cambiar arbitrariamente. Por ejemplo, cuando un usuario puede guardar citas de cambio posteriores.
Recomiendo no usar un campo DATETIME o TIMESTAMP. Si desea representar un día específico como un todo (como un cumpleaños), use un tipo de FECHA, pero si está siendo más específico que eso, probablemente esté interesado en registrar un momento real en lugar de una unidad de tiempo (día, semana, mes, año). En lugar de usar un DATETIME o TIMESTAMP, use un BIGINT y simplemente almacene el número de milisegundos desde la época (System.currentTimeMillis () si está usando Java). Esto tiene varias ventajas:
Este problema está estrechamente relacionado con cómo debe almacenar un valor monetario (es decir, $ 1.99) en una base de datos. ¿Debería usar un decimal, o el tipo de dinero de la base de datos, o lo peor de todo, un doble? Las 3 opciones son terribles, por muchas de las mismas razones mencionadas anteriormente. La solución es almacenar el valor del dinero en centavos usando BIGINT, y luego convertir centavos a dólares cuando muestra el valor al usuario. El trabajo de la base de datos es almacenar datos y NO interpretarlos. Todos estos tipos de datos sofisticados que ve en las bases de datos (especialmente Oracle) agregan poco y lo inician en el camino hacia el bloqueo de proveedores.
TIMESTAMP es de 4 bytes Vs 8 bytes para DATETIME.
http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html
Pero como dijo scronide, tiene un límite inferior para el año 1970. Sin embargo, es genial para cualquier cosa que pueda suceder en el futuro;)
TIMESTAMP es de cuatro bytes frente a ocho bytes para DATETIME.
Las marcas de tiempo también son más ligeras en la base de datos e indexadas más rápido.
El tipo DATETIME se usa cuando necesita valores que contienen información de fecha y hora. MySQL recupera y muestra los valores DATETIME en formato 'AAAA-MM-DD HH: MM: SS'. El rango admitido es '1000-01-01 00:00:00' a '9999-12-31 23:59:59'.
El tipo de datos TIMESTAMP tiene un rango de '1970-01-01 00:00:01' UTC a '2038-01-09 03:14:07' UTC. Tiene diferentes propiedades, según la versión de MySQL y el modo SQL en el que se ejecuta el servidor.
Depende de la aplicación, de verdad.
Considere configurar una marca de tiempo de un usuario en un servidor en Nueva York para una cita en Sanghai. Ahora, cuando el usuario se conecta en Sanghai, accede a la misma marca de tiempo de la cita desde un servidor duplicado en Tokio. Verá la cita en la hora de Tokio, compensada de la hora original de Nueva York.
Entonces, para los valores que representan el tiempo del usuario, como una cita o un horario, la fecha y hora es mejor. Permite al usuario controlar la fecha y hora exactas deseadas, independientemente de la configuración del servidor. La hora establecida es la hora establecida, no se ve afectada por la zona horaria del servidor, la zona horaria del usuario o por los cambios en la forma en que se calcula el horario de verano (sí, sí cambia).
Por otro lado, para los valores que representan la hora del sistema, como las transacciones de pago, las modificaciones de tablas o el registro, utilice siempre marcas de tiempo. El sistema no se verá afectado al mover el servidor a otra zona horaria, o al comparar entre servidores en diferentes zonas horarias.
Las marcas de tiempo también son más ligeras en la base de datos e indexadas más rápido.
Cualquier marco front-end reciente (Angular 1/2, react, Vue, ...) puede convertir fácil y automáticamente su fecha y hora UTC a hora local.
Adicionalmente:
(A menos que sea probable que cambie la zona horaria de sus servidores)
Ejemplo con AngularJs
// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...
// font-end Output the localised time
{{item.my_datetime | date :'medium' }}
Todos los formatos de hora localizados disponibles aquí: https://docs.angularjs.org/api/ng/filter/date
SET time_zone = '+0:00';
para UTC.
Un timestamp
campo es un caso especial del datetime
campo. Puede crear timestamp
columnas para tener propiedades especiales; se puede configurar para actualizarse en crear y / o actualizar.
En términos de bases de datos "más grandes", timestamp
tiene un par de desencadenantes de casos especiales.
Lo que es correcto depende completamente de lo que quieres hacer.
TIMESTAMP siempre está en UTC (es decir, segundos transcurridos desde 1970-01-01, en UTC), y su servidor MySQL lo convierte automáticamente a la fecha / hora para la zona horaria de conexión. A largo plazo, TIMESTAMP es el camino a seguir porque sabe que sus datos temporales siempre estarán en UTC. Por ejemplo, no arruinará sus fechas si migra a un servidor diferente o si cambia la configuración de la zona horaria en su servidor.
Nota: la zona horaria de conexión predeterminada es la zona horaria del servidor, pero esto puede (debería) cambiarse por sesión (ver SET time_zone = ...
).
Comparación entre DATETIME, TIMESTAMP y DATE
¿Qué es esa [.fracción]?
Fuentes:
Siempre usaría una marca de tiempo Unix cuando trabaje con MySQL y PHP. La razón principal de esto es que el método de fecha predeterminado en PHP usa una marca de tiempo como parámetro, por lo que no sería necesario analizar.
Para obtener la marca de tiempo actual de Unix en PHP, solo hazlo time();
y en MySQL do SELECT UNIX_TIMESTAMP();
.
Vale la pena señalar que en MySQL puede usar algo en la línea de abajo al crear las columnas de su tabla:
on update CURRENT_TIMESTAMP
Esto actualizará el tiempo en cada instancia que modifique una fila y, a veces, es muy útil para almacenar la última información de edición. Sin embargo, esto solo funciona con marca de tiempo, no con fecha y hora.
Según mi experiencia, si desea un campo de fecha en el que la inserción se realice solo una vez y no desea tener ninguna actualización u otra acción en ese campo en particular, vaya con la fecha y hora .
Por ejemplo, considere una user
tabla con un campo FECHA DE REGISTRO . En esa user
tabla, si desea saber la última hora de inicio de sesión de un usuario en particular, vaya con un campo de tipo de marca de tiempo para que el campo se actualice.
Si está creando la tabla desde phpMyAdmin, la configuración predeterminada actualizará el campo de marca de tiempo cuando ocurra una actualización de fila. Si su marca de tiempo archivada no se actualiza con la actualización de fila, puede usar la siguiente consulta para hacer que un campo de marca de tiempo se actualice automáticamente.
ALTER TABLE your_table
MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
El tipo de datos de marca de tiempo almacena la fecha y la hora, pero en formato UTC, no en el formato de zona horaria actual como lo hace datetime. Y cuando obtiene datos, la marca de tiempo nuevamente convierte eso en la hora actual de la zona horaria.
Supongamos que está en EE. UU. Y obtiene datos de un servidor que tiene una zona horaria de EE. UU. Luego obtendrá la fecha y la hora de acuerdo con la zona horaria de EE. UU. La columna de tipo de datos de marca de tiempo siempre se actualiza automáticamente cuando se actualiza su fila. Por lo tanto, puede ser útil rastrear cuándo se actualizó una fila en particular la última vez.
Para obtener más detalles, puede leer la publicación del blog Timestamp Vs Datetime .
SET time_zone = '+0:00';
(UTC aquí) para asegurarse de lo que obtiene / establece a partir de los TIMESTAMP
valores y evitar depender del valor predeterminado de time_zone del servidor que podría cambiar.
Siempre uso una marca de tiempo de Unix, simplemente para mantener la cordura al tratar con mucha información de fecha y hora, especialmente al realizar ajustes para zonas horarias, sumar / restar fechas, y similares. Al comparar marcas de tiempo, esto excluye los factores complicados de la zona horaria y le permite ahorrar recursos en el procesamiento del lado del servidor (ya sea código de aplicación o consultas de la base de datos) en el sentido de que utiliza aritmética liviana en lugar de sumar / restar fecha y hora más pesados funciones
Otra cosa que vale la pena considerar:
Si está compilando una aplicación, nunca sabrá cómo podrían usarse sus datos en el futuro. Si termina teniendo que, por ejemplo, comparar un montón de registros en su conjunto de datos, con, digamos, un montón de elementos de una API de terceros, y decir, ponerlos en orden cronológico, estará feliz de tener Marcas de tiempo Unix para sus filas. Incluso si decide usar las marcas de tiempo de MySQL, almacene una marca de tiempo de Unix como seguro.
En mi caso, configuro UTC como zona horaria para todo: el sistema, el servidor de bases de datos, etc., cada vez que puedo. Si mi cliente requiere otra zona horaria, entonces lo configuro en la aplicación.
Casi siempre prefiero las marcas de tiempo en lugar de los campos de fecha y hora, porque las marcas de tiempo incluyen la zona horaria implícitamente. Entonces, desde el momento en que los usuarios de diferentes zonas horarias tendrán acceso a la aplicación y desea que vean las fechas y horas en su zona horaria local, este tipo de campo hace que sea bastante fácil hacerlo si los datos se guardan en campos de fecha y hora .
Como un plus, en el caso de una migración de la base de datos a un sistema con otra zona horaria, me sentiría más seguro usando marcas de tiempo. No quiere decir posibles problemas al calcular las diferencias entre dos momentos con un cambio de horario de verano en el medio y que necesita una precisión de 1 hora o menos.
Entonces, para resumir, valoro estas ventajas de la marca de tiempo:
Por todas estas razones, elijo los campos UTC y marca de hora cuando sea posible. Y evito los dolores de cabeza;)
warranties.expires_at
no podría ser una marca de tiempo MySQL.
Tenga cuidado con el cambio de marca de tiempo cuando hace una instrucción UPDATE en una tabla. Si tiene una tabla con las columnas 'Nombre' (varchar), 'Edad' (int) y 'Fecha_Agregada' (marca de tiempo) y ejecuta la siguiente instrucción DML
UPDATE table
SET age = 30
entonces cada valor individual en su columna 'Fecha_Agregada' se cambiaría a la marca de tiempo actual.
ON UPDATE CURRENT_TIMESTAMP
Referencia tomada de este artículo:
Las principales diferencias:
TIMESTAMP se utiliza para rastrear los cambios en los registros y actualizar cada vez que se cambia el registro. DATETIME se utiliza para almacenar valores específicos y estáticos que no se ven afectados por ningún cambio en los registros.
TIMESTAMP también se ve afectado por diferentes ajustes relacionados con la ZONA HORARIA. DATETIME es constante.
TIMESTAMP convirtió internamente la zona horaria actual a UTC para el almacenamiento, y durante la recuperación se convirtió de nuevo a la zona horaria actual. DATETIME no puede hacer esto.
Rango admitido TIMESTAMP: '1970-01-01 00:00:01' UTC a '2038-01-19 03:14:07' UTC DATETIME rango admitido: '1000-01-01 00:00:00' a '9999 -12-31 23:59:59 ′
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP | DATETIME |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP requires 4 bytes. | DATETIME requires 8 bytes. |
| Timestamp is the number of seconds that have elapsed since January 1, 1970 00:00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format. |
| TIMESTAMP supported range: ‘1970-01-01 00:00:01′ UTC to ‘2038-01-19 03:14:07′ UTC. | DATETIME supported range: ‘1000-01-01 00:00:00′ to ‘9999-12-31 23:59:59′ |
| TIMESTAMP during retrieval converted back to the current time zone. | DATETIME can not do this. |
| TIMESTAMP is used mostly for metadata i.e. row created/modified and audit purpose. | DATETIME is used mostly for user-data. |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
Otra diferencia entre Timestamp y Datetime es que en Timestamp no puede establecer el valor predeterminado en NULL.
CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
la primera columna puede aceptar un valor NULL.
Encontré una utilidad sin igual en la capacidad de TIMESTAMP para actualizarse automáticamente en función de la hora actual sin el uso de disparadores innecesarios. Sin embargo, solo soy yo, aunque TIMESTAMP es UTC como se dijo.
Puede realizar un seguimiento de diferentes zonas horarias, por lo que si necesita mostrar una hora relativa, por ejemplo, la hora UTC es lo que desea.
La mayor diferencia es
mira esta publicación para ver problemas con la indexación de fecha y hora
Dejé de usar datetime
en mis aplicaciones después de enfrentar muchos problemas y errores relacionados con las zonas horarias. En mi humilde opinión el uso timestamp
es mejor que datetime
en la mayoría de los casos .
Cuando preguntas qué hora es y la respuesta viene como algo así como '2019-02-05 21:18:30', que no está completa, respuesta no definida porque carece de otra parte, ¿en qué zona horaria? Washington Moscú Beijing ?
El uso de la fecha y hora sin la zona horaria significa que su aplicación solo maneja 1 zona horaria, sin embargo, las marcas de tiempo le brindan los beneficios datetime
y la flexibilidad de mostrar el mismo punto exacto de tiempo en diferentes zonas horarias.
Aquí hay algunos casos que harán que te arrepientas de usar datetime
y deseen almacenar tus datos en marcas de tiempo.
Para la comodidad de sus clientes, desea mostrarles las horas en función de sus zonas horarias preferidas sin hacer que hagan los cálculos y convertir la hora a su zona horaria significativa. todo lo que necesita es cambiar la zona horaria y todo el código de su aplicación será el mismo. (En realidad, siempre debe definir la zona horaria al inicio de la aplicación, o solicitar el procesamiento en caso de aplicaciones PHP)
SET time_zone = '+2:00';
cambiaste el país en el que te hospedas y continúas tu trabajo de mantener los datos mientras los ves en una zona horaria diferente (sin cambiar los datos reales).
datetime
= la aplicación admite 1 zona horaria (tanto para insertar como para seleccionar)
timestamp
= la aplicación admite cualquier zona horaria (tanto para insertar como para seleccionar)
Esta respuesta es solo para resaltar la flexibilidad y la facilidad de las marcas de tiempo cuando se trata de zonas horarias, no cubre ninguna otra diferencia como el tamaño de la columna, el rango o la fracción .
date
y otros campos usan timestamp
en una tabla? Creo que causará un nuevo problema porque los datos que se filtran where
no están de acuerdo con los cambios de la zona horaria.
date
columna antes de enviar la consulta.
A TIMESTAMP
requiere 4 bytes, mientras que a DATETIME
requiere 8 bytes.
Me gusta una marca de tiempo de Unix, porque puedes convertir a números y solo preocuparte por el número. Además, suma / resta y obtiene duraciones, etc. Luego convierte el resultado a Fecha en cualquier formato. Este código descubre cuánto tiempo en minutos pasó entre una marca de tiempo de un documento y la hora actual.
$date = $item['pubdate']; (etc ...)
$unix_now = time();
$result = strtotime($date, $unix_now);
$unix_diff_min = (($unix_now - $result) / 60);
$min = round($unix_diff_min);