Pregunta

¿Recomendaría usar un datetime o una timestamp , y por qué (usando MySQL)?

Estoy trabajando con PHP en el lado del servidor.

¿Fue útil?

Solución

Las marcas de tiempo en MySQL se usan generalmente 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 utilizar un campo de fecha y hora.

Si quiso decir que quiere decidir entre usar una marca de tiempo de UNIX o un campo de fecha y hora nativo de MySQL, vaya con el formato nativo. Puedes hacer cálculos dentro de MySQL de esa manera (" SELECT DATE_ADD (my_datetime, INTERVAL 1 DAY) ") y es sencillo cambiar el formato del valor a una marca de tiempo UNIX (" SELECT UNIX_TIMESTAMP (my_datetime) " ) cuando consulta el registro si desea operar en él con PHP.

Otros consejos

En MySQL 5 y superior, los valores de TIMESTAMP se convierten de la zona horaria actual a UTC para su 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.)

De forma predeterminada, 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 otra cosa que no sean los metadatos de fila (fecha de creación o modificación).

Como mencionado 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 de DATETIME en el formato 'YYYY-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. almacenamiento fecha de nacimiento.

Los ejemplos a continuación muestran cómo el tipo de fecha TIMESTAMP cambió los valores después de cambiar la zona horaria a 'america / new_york' donde DATETIME no ha cambiado.

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 encontrarlo útil, MySQL: Datetime Versus Timestamp Data Types .

La principal diferencia es que DATETIME es constante, mientras que TIMESTAMP se ve afectado por la configuración time_zone .

Entonces, solo importa cuando tienes & # 8212; o puede tener en el futuro & # 8212; clusters sincronizados a través de 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 los Estados Unidos, TIMESTAMP se actualizaría para reflejar el tiempo real del evento en el nuevo zona horaria, mientras que DATETIME aún reflejaría la hora del evento en la zona horaria au .

Un gran ejemplo del uso de DATETIME donde TIMESTAMP debería haberse usado es en Facebook, donde sus servidores nunca están muy seguros de la hora en que sucedieron las cosas en las distintas zonas horarias. Una vez tuve una conversación en la que el tiempo decía que estaba respondiendo a los mensajes antes de que realmente se enviara el mensaje. (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 los tiempos se hubieran publicado en lugar de sincronizarse).

Tomo esta decisión sobre una base semántica.

Utilizo 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 por parte del usuario.

Utilizo un campo de fecha y hora cuando la fecha / hora se puede establecer y cambiar arbitrariamente. Por ejemplo, cuando un usuario puede guardar citas posteriores.

TIMESTAMP es de 4 bytes frente a 8 bytes para DATETIME.

http://dev.mysql.com/doc/ refman / 5.0 / es / storage-Requirements.html

Pero, como dice Scronide, tiene un límite inferior para el año 1970. Aunque es genial para cualquier cosa que pueda suceder en el futuro;)

Recomiendo usar ninguno un DATETIME o un campo TIMESTAMP. Si desea representar un día específico en su totalidad (como un cumpleaños), use un tipo de FECHA, pero si es más específico, 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 la cantidad de milisegundos desde la época (System.currentTimeMillis () si está usando Java). Esto tiene varias ventajas:

  1. Evita el bloqueo de proveedores. Casi todas las bases de datos admiten enteros de manera relativamente similar. Supongamos que desea moverse a otra base de datos. ¿Quiere preocuparse por las diferencias entre los valores DATETIME de MySQL y cómo los define Oracle? Incluso entre diferentes versiones de MySQL, TIMESTAMPS tiene un nivel diferente de precisión. Solo recientemente, MySQL soportó milisegundos en las marcas de tiempo.
  2. No hay problemas de zona horaria. Se han realizado algunos comentarios interesantes sobre lo que sucede con las zonas horarias con los diferentes tipos de datos. ¿Pero es este conocimiento común, y sus compañeros de trabajo se tomarán el tiempo para aprenderlo? Por otro lado, es bastante difícil arruinar el cambio de un BigINT en un java.util.Date. Usar un BIGINT causa muchos problemas con las zonas horarias que se quedan en el camino.
  3. No te preocupes por los rangos o la precisión. No tiene que preocuparse por lo que se corta en los rangos de fechas futuras (TIMESTAMP solo va hasta 2038).
  4. Integración de herramientas de terceros. Al usar un número entero, es trivial para las herramientas de terceros (por ejemplo, EclipseLink) para interactuar con la base de datos. No todas las herramientas de terceros tendrán la misma comprensión de " datetime " como hace MySQL. ¿Quieres probar y averiguar en Hibernate si deberías usar un objeto java.sql.TimeStamp o java.util.Date si estás usando estos tipos de datos personalizados? El uso de los tipos de datos base hace que el uso con herramientas de terceros sea trivial.

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? Todas las 3 de estas opciones son terribles, por muchas de las razones mencionadas anteriormente. La solución es almacenar el valor del dinero en centavos utilizando BIGINT y luego convertir los centavos a dólares cuando se muestra el valor al usuario. El trabajo de la base de datos es almacenar datos y NO interpretar esos datos. Todos estos tipos de datos sofisticados que se ven en las bases de datos (especialmente Oracle) agregan poco, y le ayudan a comenzar el bloqueo del proveedor.

  1. TIMESTAMP es de cuatro bytes frente a ocho bytes para DATETIME.

  2. Las marcas de tiempo también son más claras en la base de datos y se indexan más rápido.

  3. El tipo DATETIME se usa cuando necesita valores que contienen información de fecha y hora. MySQL recupera y muestra los valores de DATETIME en el formato 'YYYY-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.

  1. DATETIME es constante, mientras que TIMESTAMP se efectúa mediante la configuración de time_zone.

Depende de la aplicación, realmente.

Considere establecer una marca de tiempo por 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 fecha y hora de la cita desde un servidor duplicado en Tokio. Verá la cita en el horario de Tokio, compensado con el horario original de Nueva York.

Entonces, para los valores que representan el tiempo del usuario como una cita o un horario, datetime 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 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í cambia).

Por otra parte, para los valores que representan la hora del sistema como las transacciones de pago, las modificaciones de la tabla o el registro, siempre use las 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 livianas en la base de datos y se indexan más rápido.

2016 + : lo que aconsejo es configurar tu zona horaria Mysql en UTC y usar DATETIME:

Cualquier marco de front-end reciente (Angular 1/2, reaccionar, Vue, ...) puede convertir fácil y automáticamente su fecha y hora UTC a hora local.

Además:

(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' }}

Todo el formato de hora localizada disponible aquí: https://docs.angularjs.org/api/ng/filter/date

Un campo

timestamp es un caso especial del campo datetime . Puede crear columnas de timestamp para tener propiedades especiales; se puede configurar para actualizarse, ya sea en crear y / o actualizar.

En " más grande " términos de la base de datos, timestamp tiene un par de activadores de casos especiales.

Lo que es correcto depende completamente de lo que quieras hacer.

TIMESTAMP está siempre 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ás las fechas si migras a un servidor diferente o si cambias la configuración de la zona horaria en tu 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

 introduce la descripción de la imagen aquí

¿Qué es ese [.fraction]?

  • Un valor DATETIME o TIMESTAMP puede incluir un fraccionario de cola Segundos parte en hasta microsegundos (6 dígitos) de precisión. En en particular, cualquier parte fraccionaria en un valor insertado en un DATETIME o la columna TIMESTAMP se almacena en lugar de descartarse. Esto es, por supuesto, opcional.

Fuentes:

Vale la pena señalar que en MySQL puede usar algo como las líneas a continuación al crear sus columnas de tabla:

on update CURRENT_TIMESTAMP

Esto actualizará el tiempo en cada instancia que modifique una fila y, a veces, es muy útil para la última información de edición almacenada. Sin embargo, esto solo funciona con la marca de tiempo, no con fecha y hora.

Siempre usaría una marca de tiempo Unix al trabajar con MySQL y PHP. La razón principal de esto es que el método predeterminado date en PHP usa una la marca de tiempo como parámetro, por lo que no sería necesario realizar un análisis.

Para obtener la marca de tiempo actual de Unix en PHP, solo haga time ();
y en MySQL haga SELECT UNIX_TIMESTAMP (); .

Desde mi experiencia, si desea un campo de fecha en el que la inserción se realiza solo una vez y no desea tener ninguna actualización ni ninguna otra acción en ese campo en particular, vaya con fecha y hora .

Por ejemplo, considere una tabla usuario con un campo FECHA DE REGISTRO . En esa tabla de usuario , si desea saber la última hora de inicio de sesión de un usuario en particular, vaya con un campo de marca de hora para que el campo se actualice.

Si está creando la tabla desde phpMyAdmin , la configuración predeterminada actualizará la marca de tiempo campo cuando ocurre una actualización de la fila. Si su marca de tiempo no se actualiza con la actualización de la fila, puede usar la siguiente consulta para hacer que el campo 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 hora almacena la fecha y la hora, pero en formato UTC, no en el formato de zona horaria actual como lo hace datetime. Y cuando recuperas datos, la marca de tiempo lo convierte nuevamente 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 hacer un seguimiento de cuándo se actualizó una fila en particular la última vez.

Para más detalles, puede leer la publicación del blog Timestamp Vs Datetime .

Siempre uso una marca de tiempo de Unix, simplemente para mantener la cordura cuando se trata de mucha información de fecha y hora, especialmente cuando se realizan ajustes para zonas horarias, fechas de adición / resta, etc. Al comparar las marcas de tiempo, esto excluye los factores que complican la zona horaria y le permite ahorrar recursos en el procesamiento del lado del servidor (ya sea el código de la aplicación o las consultas de la base de datos), ya que hace uso de la aritmética de peso ligero en lugar de la fecha y hora más pesadas. funciones

Otra cosa que vale la pena considerar:

Si está creando una aplicación, nunca se sabe cómo deben usarse sus datos en el futuro. Si terminas teniendo que, digamos, comparar un montón de registros en tu conjunto de datos, con, digamos, un montón de elementos de una API de terceros, y decir, ponerlos en orden cronológico, estarás feliz de tener Marcas de tiempo Unix para tus filas. Incluso si decide utilizar las marcas de tiempo de MySQL, almacene una marca de tiempo de Unix como seguro.

Tenga cuidado con el cambio de fecha y hora cuando realice una instrucción UPDATE en una tabla. Si tiene una tabla con las columnas 'Nombre' (varchar), 'Edad' (int) y 'Fecha_administrada' (marca de tiempo) y ejecuta la siguiente declaración DML

UPDATE table
SET age = 30

entonces cada valor único en su columna 'Date_Added' se cambiará a la marca de tiempo actual.

Referencia tomada de este artículo:

Las principales diferencias:

TIMESTAMP se usa para rastrear los cambios en los registros y actualizar cada vez que se cambia el registro. DATETIME se usa 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 su almacenamiento, y durante la recuperación se convirtió nuevamente a la zona horaria actual. DATETIME no puede hacer esto.

Rango soportado por TIMESTAMP: & # 8216; 1970-01-01 00: 00: 01 & # 8242; UTC a & # 8216; 2038-01-19 03: 14: 07 & # 8242; UTC Rango soportado DATETIME: & # 8216; 1000-01-01 00: 00: 00 & # 8242; a & # 8216; 9999-12-31 23: 59: 59 & # 8242;

En mi caso, configuro UTC como una zona horaria para todo: el sistema, el servidor de bases de datos, etc. cada vez que puedo. Si mi cliente requiere otra zona horaria, la 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 implícitamente la zona horaria. Por lo tanto, desde el momento en que se accederá a la aplicación desde usuarios de diferentes zonas horarias y desea que vean las fechas y horas en su zona horaria local, este tipo de campo hace que sea más fácil hacerlo que si los datos se guardaran en campos de fecha y hora. .

Como ventaja adicional, 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 al usar marcas de tiempo. Por no decir posibles problemas al calcular las diferencias entre dos momentos con un cambio de hora del sumador en el medio y una precisión de 1 hora o menos.

Entonces, para resumir, valoro estas ventajas de la marca de tiempo:

  • listo para usar en aplicaciones internacionales (zona horaria múltiple)
  • migraciones fáciles entre zonas horarias
  • bastante fácil de calcular diferencias (solo reste ambas marcas de tiempo)
  • no se preocupe por las fechas dentro o fuera de un período de verano

Por todas estas razones, elijo UTC & amp; campos de marca de tiempo donde sea posible. Y evito dolores de cabeza;)

La principal diferencia es

  • un ÍNDICE en la marca de tiempo - funciona
  • un ÍNDICE en Datetime - No funciona

mire esto publicar para ver problemas con la indexación de Datetime

Otra diferencia entre la marca de tiempo y la fecha y la hora está en la marca de tiempo, no se puede establecer el valor predeterminado en NULL.

Encontré una utilidad insuperable en la capacidad de TIMESTAMP para actualizarse automáticamente en función de la hora actual sin el uso de activadores innecesarios. Aunque solo soy yo, aunque TIMESTAMP es UTC como se dijo.

Puede hacer un seguimiento de diferentes zonas horarias, por lo que si necesita mostrar una hora relativa, por ejemplo, la hora UTC es lo que desea.

Prefiero usar la marca de tiempo para mantener todo en un formato común y formatear los datos en código PHP o en su consulta SQL. Hay casos en los que resulta útil en su código para mantener todo en segundos.

+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       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.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+

Me gusta una marca de tiempo de Unix, porque puedes convertir a números y solo preocuparte por el número. Además, sumas / restas y obtienes duraciones, etc. Luego, convierte el resultado a Fecha en cualquier formato. Este código descubre la cantidad de tiempo en minutos transcurridos 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);

Un TIMESTAMP requiere 4 bytes, mientras que un DATETIME requiere 8 bytes.

TIMESTAMP es útil cuando tiene visitantes de diferentes países con diferentes zonas horarias. puede convertir fácilmente el TIMESTAMP a cualquier zona horaria del país

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top