Question

Recommanderiez-vous d'utiliser un datetime ou un timestamp , et pourquoi (avec MySQL)?

Je travaille avec PHP côté serveur.

Était-ce utile?

La solution

Les horodatages dans MySQL sont généralement utilisés pour suivre les modifications apportées aux enregistrements et sont souvent mis à jour chaque fois que l'enregistrement est modifié. Si vous souhaitez stocker une valeur spécifique, vous devez utiliser un champ datetime.

Si vous vouliez choisir d'utiliser un horodatage UNIX ou un champ natif de date / heure MySQL, choisissez le format natif. Vous pouvez faire des calculs dans MySQL de cette façon ("SELECT DATE_ADD (my_datetime, INTERVAL 1 DAY)") et il est simple de changer le format de la valeur en un horodatage UNIX (& SELECT; UNIX_TIMESTAMP (my_datetime) " ) lorsque vous interrogez l’enregistrement si vous souhaitez l’utiliser avec PHP.

Autres conseils

Dans MySQL 5 et versions ultérieures, les valeurs TIMESTAMP sont converties du fuseau horaire actuel en UTC pour le stockage, puis reconverties d'UTC au fuseau horaire actuel pour être récupérées. (Cela se produit uniquement pour le type de données TIMESTAMP et pas pour les autres types tels que DATETIME.)

Par défaut, le fuseau horaire actuel de chaque connexion est l'heure du serveur. Le fuseau horaire peut être défini connexion par connexion, comme décrit dans Support du fuseau horaire du serveur MySQL .

J'utilise toujours les champs DATETIME pour autre chose que les métadonnées de ligne (date de création ou de modification).

Comme mentionné dans la documentation MySQL:

  

Le type DATETIME est utilisé lorsque vous avez besoin de valeurs contenant à la fois des informations de date et d’heure. MySQL récupère et affiche les valeurs DATETIME au format 'AAAA-MM-JJ HH: MM: SS. La plage prise en charge va de «1000-01-01 00:00:00» à «9999-12-31 23:59:59».

     

...

     

Le type de données TIMESTAMP a une plage allant de "1970-01-01 00:00:01" UTC à "2038-01-09 03:14:07" UTC. Ses propriétés varient en fonction de la version de MySQL et du mode SQL dans lequel le serveur est exécuté.

Il est fort probable que vous atteigniez la limite inférieure d'utilisation de TIMESTAMP - par exemple. enregistrer la date de naissance.

Les exemples ci-dessous montrent comment le type de date TIMESTAMP a modifié les valeurs après avoir modifié le fuseau horaire en "america / new_york" DATETIME est inchangé.

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

J'ai converti ma réponse en article afin que davantage de personnes puissent trouver cela utile, MySQL: types de données Datetime par rapport à l'horodatage .

La principale différence est que DATETIME est constant alors que TIMESTAMP est affecté par le paramètre time_zone .

Cela n'a donc d'importance que lorsque vous avez (ou pourriez avoir à l'avenir) des clusters synchronisés sur plusieurs fuseaux horaires.

En termes plus simples: Si j’ai une base de données en Australie et que je fais un dump de cette base pour synchroniser / remplir une base de données en Amérique, le TIMESTAMP sera mis à jour pour refléter le temps réel de l’événement dans la nouvelle fuseau horaire, tandis que DATETIME indique toujours l’heure de l’événement dans le fuseau horaire Au .

Un bon exemple d'utilisation de DATETIME où TIMESTAMP aurait dû être utilisé est Facebook, où leurs serveurs ne sont jamais tout à fait sûr du contenu de l'heure dans différents fuseaux horaires. Une fois, j’ai eu une conversation pendant laquelle le temps a dit que je répondais aux messages avant que le message ne soit réellement envoyé. (Ceci, bien sûr, pourrait également avoir été provoqué par une mauvaise traduction du fuseau horaire dans le logiciel de messagerie si les heures avaient été affichées plutôt que synchronisées.)

Je prends cette décision sur une base sémantique.

J'utilise un horodatage lorsque je dois enregistrer un moment (plus ou moins) fixe. Par exemple, lorsqu’un enregistrement a été inséré dans la base de données ou lorsqu’une action de l’utilisateur a eu lieu.

J'utilise un champ date / heure lorsque la date / heure peut être définie et modifiée de manière arbitraire. Par exemple, lorsqu'un utilisateur peut enregistrer des rendez-vous modifiés ultérieurement.

TIMESTAMP est de 4 octets contre 8 octets pour DATETIME.

http://dev.mysql.com/doc/ refman / 5.0 / fr / storage-requirements.html

Mais comme le dit Scronide, il a une limite inférieure de 1970. C’est génial pour tout ce qui pourrait arriver à l’avenir cependant;)

Je recommande d'utiliser ni un champ DATETIME ou TIMESTAMP. Si vous voulez représenter un jour spécifique dans son ensemble (comme un anniversaire), utilisez un type DATE, mais si vous êtes plus précis que cela, vous êtes probablement intéressé par l'enregistrement d'un moment réel par opposition à une unité de heure (jour, semaine, mois, année). Au lieu d'utiliser DATETIME ou TIMESTAMP, utilisez un BIGINT et enregistrez simplement le nombre de millisecondes écoulé depuis l'époque (System.currentTimeMillis () si vous utilisez Java). Cela présente plusieurs avantages:

  1. Vous évitez le blocage du vendeur. Presque toutes les bases de données supportent les entiers de la même manière Supposons que vous souhaitiez passer à une autre base de données. Voulez-vous vous inquiéter des différences entre les valeurs DATETIME de MySQL et comment Oracle les définit? Même parmi les différentes versions de MySQL, TIMESTAMPS a un niveau de précision différent. Ce n'est que récemment que MySQL a pris en charge les millisecondes dans les horodatages.
  2. Aucun problème de fuseau horaire. Il y a eu quelques commentaires perspicaces sur ce qui se passe avec les fuseaux horaires avec les différents types de données. Mais est-ce une connaissance commune et vos collègues vont-ils tous prendre le temps de l'apprendre? Par contre, il est assez difficile de perdre son temps à transformer un BigINT en un java.util.Date. L'utilisation d'un BIGINT provoque de nombreux problèmes avec les fuseaux horaires.
  3. Pas de soucis concernant les portées ou la précision. Vous n'avez pas à vous soucier de ce qui sera écourté par les fourchettes de dates futures (TIMESTAMP ne va que jusqu'en 2038).
  4. Intégration d’outils tiers. En utilisant un entier, il est facile pour les outils tiers (par exemple, EclipseLink) d’interfacer avec la base de données. Tous les outils tiers ne comprendront pas de la même manière un "date-heure". comme le fait MySQL. Vous voulez essayer de savoir dans Hibernate si vous devez utiliser un objet java.sql.TimeStamp ou java.util.Date si vous utilisez ces types de données personnalisés? L'utilisation de vos types de données de base facilite l'utilisation d'outils tiers.

Ce problème est étroitement lié au stockage d’une valeur monétaire (1,99 $) dans une base de données. Devez-vous utiliser un nombre décimal, ou le type Money de la base de données, ou pire un double? Ces trois options sont terribles, pour bon nombre des raisons énumérées ci-dessus. La solution consiste à stocker la valeur de l'argent en cents à l'aide de BIGINT, puis à convertir les cents en dollars lorsque vous affichez la valeur à l'utilisateur. Le travail de la base de données consiste à stocker des données, et non à interpréter ces données. Tous ces types de données sophistiqués que vous voyez dans les bases de données (en particulier Oracle) n’ajoutent que peu, et vous permettent de vous immiscer dans l’immobilisation du fournisseur.

  1. TIMESTAMP est quatre octets contre huit octets pour DATETIME.

  2. Les horodatages sont également plus légers sur la base de données et indexés plus rapidement.

  3. Le type DATETIME est utilisé lorsque vous avez besoin de valeurs contenant à la fois des informations de date et d'heure. MySQL récupère et affiche les valeurs DATETIME dans & # 8216; AAAA-MM-JJ HH: MM: SS & # 8217; format. La plage prise en charge est & # 8217; 1000-01-01 00: 00: 00 & # 8242; au & # 8217; 9999-12-31 23: 59: 59 & # 8242;.

Le type de données TIMESTAMP couvre une plage de & # 8217; 1970-01-01 00: 00: 00 & # 8242; UTC jusqu'au & # 8217; 2038-01-09 03: 14: 07 & # 8242; UTC. Ses propriétés varient en fonction de la version de MySQL et du mode SQL dans lequel le serveur est exécuté.

  1. DATETIME est constant tandis que TIMESTAMP est affecté par le paramètre time_zone.

Cela dépend vraiment de l'application.

Envisagez de définir un horodatage par un utilisateur sur un serveur à New York pour un rendez-vous à Sanghai. Désormais, lorsque l'utilisateur se connecte à Sanghai, il accède au même horodatage à partir d'un serveur mis en miroir à Tokyo. Il verra son rendez-vous à l'heure de Tokyo, décalé par rapport à l'heure de New York.

Donc, pour les valeurs qui représentent l'heure de l'utilisateur, comme un rendez-vous ou une planification, datetime est préférable. Il permet à l'utilisateur de contrôler la date et l'heure exactes souhaitées, quels que soient les paramètres du serveur. L'heure définie est l'heure définie, non affectée par le fuseau horaire du serveur, le fuseau horaire de l'utilisateur ou les modifications apportées au mode de calcul de l'heure d'été (oui, cela change).

D'un autre côté, utilisez toujours des horodatages pour les valeurs qui représentent l'heure du système, telles que les transactions de paiement, les modifications de table ou la journalisation. Le système ne sera pas affecté par le déplacement du serveur vers un autre fuseau horaire ou par la comparaison entre serveurs de fuseaux horaires différents.

Les horodatages sont également plus légers sur la base de données et indexés plus rapidement.

2016 + : je vous conseille de régler votre fuseau horaire Mysql sur UTC et d'utiliser DATETIME:

Tout framework frontal récent (Angular 1/2, react, Vue, ...) peut facilement et automatiquement convertir votre date / heure UTC en heure locale.

De plus:

(sauf si vous êtes susceptible de changer le fuseau horaire de vos serveurs)

Exemple avec 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' }}

Tous les formats d’heure localisés sont disponibles ici: https://docs.angularjs.org/api/ng/filter/date

Un champ timestamp est un cas particulier du champ datetime . Vous pouvez créer des colonnes timestamp pour avoir des propriétés spéciales; il peut être configuré pour se mettre à jour lui-même lors de la création et / ou de la mise à jour.

Dans " plus grand " termes de base de données, timestamp contient quelques déclencheurs de cas spéciaux.

La bonne dépend de ce que vous voulez faire.

TIMESTAMP est toujours en UTC (c'est-à-dire, secondes écoulées depuis le 01/01/1970, en UTC), et votre serveur MySQL le convertit automatiquement en date / heure pour le fuseau horaire de connexion. TIMESTAMP est la solution à long terme, car vous savez que vos données temporelles seront toujours en UTC. Par exemple, vous ne foirez pas vos dates si vous migrez vers un autre serveur ou si vous modifiez les paramètres de fuseau horaire sur votre serveur.

Remarque: le fuseau horaire de connexion par défaut est le fuseau horaire du serveur, mais cela peut (devrait) être changé par session (voir SET time_zone = ... ).

Comparaison entre DATETIME, TIMESTAMP et DATE

 entrez la description de l'image ici

Qu'est-ce que cette [.fraction]?

  • Une valeur DATETIME ou TIMESTAMP peut inclure une fraction décimale secondes dans une précision allant jusqu’à quelques microsecondes (6 chiffres). Dans en particulier, toute partie décimale d’une valeur insérée dans une DATETIME ou la colonne TIMESTAMP est stockée plutôt que rejetée. Ceci est bien sûr facultatif.

Sources:

Il est intéressant de noter que dans MySQL, vous pouvez utiliser quelque chose comme indiqué ci-dessous lors de la création des colonnes de votre tableau:

on update CURRENT_TIMESTAMP

Ceci mettra à jour l'heure à chaque fois que vous modifiez une ligne et est parfois très utile pour les informations de dernière modification stockées. Cela ne fonctionne qu'avec l'horodatage, pas avec datetime cependant.

J'utiliserais toujours un horodatage Unix pour travailler avec MySQL et PHP. La raison principale en est que la méthode date par défaut de PHP utilise un horodatage en tant que paramètre, il n'y aurait donc pas d'analyse nécessaire.

Pour obtenir l'horodatage Unix actuel en PHP, utilisez simplement time ();

et dans MySQL, faites SELECT UNIX_TIMESTAMP (); .

D'après mes expériences, si vous souhaitez un champ de date dans lequel l'insertion ne se produit qu'une seule fois et que vous ne souhaitez effectuer aucune mise à jour ni aucune action sur ce champ particulier, utilisez heure de la date .

Par exemple, considérons une table utilisateur avec un champ DATE D'ENREGISTREMENT . Dans cette table user , si vous souhaitez connaître la dernière heure de connexion d'un utilisateur particulier, utilisez un champ de type horodatage pour que le champ soit mis à jour.

Si vous créez la table à partir de phpMyAdmin , le paramètre par défaut mettra à jour l'horodatage . champ lorsqu'une mise à jour de ligne est effectuée. Si votre horodatage ne se met pas à jour avec la mise à jour de la ligne, vous pouvez utiliser la requête suivante pour qu'un champ horodatage soit automatiquement mis à jour.

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

Le type de données d'horodatage stocke la date et l'heure, mais au format UTC et non au format de fuseau horaire actuel, contrairement à datetime. Et lorsque vous récupérez des données, l'horodatage les convertit à nouveau dans l'heure du fuseau horaire actuel.

Supposons donc que vous êtes aux États-Unis et que vous obtenez les données d’un serveur dont le fuseau horaire est celui des États-Unis. Ensuite, vous obtiendrez la date et l'heure en fonction du fuseau horaire des États-Unis. La colonne de type de données d'horodatage est toujours automatiquement mise à jour lorsque sa ligne est mise à jour. Il peut donc être utile de savoir quand une ligne particulière a été mise à jour la dernière fois.

Pour plus d'informations, vous pouvez lire l'article du blog Timestamp Vs Datetime . .

J'utilise toujours un horodatage Unix, simplement pour conserver son intégrité physique lors de la gestion de nombreuses informations de date / heure, en particulier lors de l'ajustement des fuseaux horaires, de l'ajout / de la soustraction de dates, etc. Lorsque vous comparez des horodatages, cela exclut les facteurs de complexité du fuseau horaire et vous permet d'économiser des ressources dans votre traitement côté serveur (qu'il s'agisse de requêtes de code d'application ou de base de données), dans la mesure où vous utilisez une arithmétique légère plutôt qu'un ajout / soustraction de date / heure plus lourd. les fonctions.

Une autre chose à considérer:

Si vous construisez une application, vous ne savez jamais comment vos données pourraient être utilisées ultérieurement. Si, par exemple, vous devez comparer un ensemble d'enregistrements de votre ensemble de données avec, par exemple, un ensemble d'éléments provenant d'une API tierce, et dites-les, par ordre chronologique, vous serez heureux d'avoir Timestamps Unix pour vos lignes. Même si vous décidez d'utiliser les horodatages MySQL, stockez-les comme assurance.

Méfiez-vous des changements d'horodatage lorsque vous effectuez une instruction UPDATE sur une table. Si vous avez une table avec les colonnes 'Nom' (varchar), 'Age' (int) et 'Date_Added' (horodatage) et que vous exécutez l'instruction DML suivante

UPDATE table
SET age = 30

alors chaque valeur de votre colonne "Date_Added" sera remplacée par l'horodatage actuel.

Référence tirée de cet article:

Les principales différences:

TIMESTAMP utilisé pour suivre les modifications apportées aux enregistrements et se mettre à jour chaque fois que l’enregistrement est modifié. DATETIME utilisé pour stocker une valeur spécifique et statique non affectée par les modifications apportées aux enregistrements.

TIMESTAMP est également affecté par différents réglages liés à TIME ZONE. DATETIME est constant.

TIMESTAMP a converti en interne le fuseau horaire actuel en UTC pour le stockage et, lors de la récupération, est reconverti dans le fuseau horaire actuel. DATETIME ne peut pas faire cela.

Plage prise en charge par TIMESTAMP: «1970-01-01 00:00:01 ' UTC à« 2038-01-19 03:14:07 ' UTC Plage prise en charge par DATETIME: «1000-01-01 00:00:00 à» 9999-12-31 23:59:59

Dans mon cas, j'ai défini l'heure UTC comme fuseau horaire pour tout: le système, le serveur de base de données, etc. chaque fois que je le peux. Si mon client a besoin d'un autre fuseau horaire, je le configure sur l'application.

Je préfère presque toujours les horodatages aux champs datetime, car les horodatages incluent implicitement le fuseau horaire. Donc, depuis le moment où l'application sera accédée par des utilisateurs de différents fuseaux horaires et que vous voulez qu'ils voient les dates et les heures dans leur fuseau horaire local, ce type de champ est assez facile à faire que si les données étaient enregistrées dans des champs datetime .

Comme avantage, dans le cas d'une migration de la base de données vers un système avec un autre fuseau horaire, je me sentirais plus à l'aise avec l'utilisation des horodatages. Pour ne pas dire les problèmes possibles lors du calcul des différences entre deux moments avec un changement d'heure d'été entre et une précision d'une heure ou moins.

Donc, pour résumer, j'apprécie les avantages de l'horodatage:

  • prêt à être utilisé sur les applications internationales (multi-fuseaux horaires)
  • migrations faciles entre les fuseaux horaires
  • assez facile à calculer les différences (il suffit de soustraire les deux horodatages)
  • ne vous inquiétez pas des dates d'entrée et de sortie d'une période d'été

Pour toutes ces raisons, j'ai choisi UTC & amp; champs d'horodatage si possible. Et j'évite les maux de tête;)

La principale différence est

regardez ceci post pour voir les problèmes liés à l'indexation Datetime

Une autre différence entre Timestamp et Datetime réside dans Timestamp, la valeur par défaut ne peut pas être NULL.

J'ai trouvé une utilité inégalée dans la capacité de TIMESTAMP à se mettre à jour automatiquement en fonction de l'heure actuelle sans utiliser de déclencheurs inutiles. C’est juste moi cependant, bien que TIMESTAMP soit au format UTC, comme il a été dit.

Il peut garder une trace sur différents fuseaux horaires. Par conséquent, si vous devez afficher une heure relative, par exemple, l'heure UTC est celle que vous souhaiteriez.

Je préfère utiliser l’horodatage afin de tout conserver dans un format brut commun et de formater les données en code PHP ou dans votre requête SQL. Dans certains cas, il est utile dans votre code de tout conserver en quelques secondes.

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

J'aime les horodatages Unix, car vous pouvez convertir des nombres et vous soucier de leur nombre. De plus, vous ajoutez / soustrayez et obtenez des durées, etc. Ensuite, convertissez le résultat en Date, quel que soit le format. Ce code recherche le temps en minutes entre un horodatage d'un document et l'heure actuelle.

$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 nécessite 4 octets, alors qu'un DATETIME nécessite 8 octets.

TIMESTAMP est utile lorsque vous avez des visiteurs de différents pays avec des fuseaux horaires différents. vous pouvez facilement convertir TIMESTAMP en n’importe quel fuseau horaire de pays

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top