J'observe un comportement inattendu lors de l'insertion/la mise à jour de NULL dans une colonne d'horodatage MySQL.
Considérez les affirmations suivantes.
create table temp(id int, hireDate timestamp default 0);
insert into temp (id) values(1);
insert into temp (id, hireDate) values(2, null);
select * from temp;
id hireDate
-----------------------------
1
2 2012-09-19 10:54:10.0
La première insertion (lorsque hiredate
n'est pas spécifié dans le code SQL, hireDate est null(0)
, ce qui est attendu.
Cependant, lorsqu'un null explicite est passé en SQL, la date actuelle est insérée, ce qui est inattendu. Pourquoi cela arrive-t-il?
Remarque: Hibernate utilise un deuxième type d’insert et pose donc un problème. Comment insérer null dans une colonne d'horodatage?
http://dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html
En outre, vous pouvez initialiser ou mettre à jour une colonne TIMESTAMP à la date et à l'heure actuelles en lui attribuant une valeur NULL, sauf si elle a été définie avec l'attribut NULL pour autoriser les valeurs NULL.
Créer la table:
create table penguins(id int primary key auto_increment, the_time timestamp NULL);
Insérer quelques lignes:
insert into penguins(the_time) values (now());
insert into penguins(the_time) values (null);
insert into penguins(the_time) values (0);
insert into penguins(the_time) values ('1999-10-10 01:02:03');
Quels tirages:
select * from penguins
1 2015-01-23 15:40:36
2
3 0000-00-00 00:00:00
4 1999-10-10 01:02:03
La colonne appelée the_time
avec le type de données: timestamp
dans la deuxième ligne a la valeur NULL.
Vous devez modifier la valeur par défaut de la colonne hireDate. La valeur par défaut doit être null
Ce
create table temp(id int, hireDate timestamp default 0);
Devrait être ceci:
create table temp(id int, hireDate timestamp null);
Ne stockez jamais de valeur d'application dans une colonne de type timestamp MySQL . Utilisez le type timestamp uniquement pour l'horodatage dynamique côté serveur de base de données (voir Attributs de colonne DEFAULT et ON UPDATE) . appelant les colonnes 'mysql_row_created_at' et 'mysql_row_updated_at'.
Sachez que MySQL stocke physiquement son type d'horodatage sous la forme d'un UNIX-Epoch-delta numérique, de sorte qu'il dispose d'un fuseau horaire UTC implicite, ce qui le rend insensible aux changements de fuseau horaire au niveau de la session (connexion AKA).
Éloignez-vous du type 'datetime', et plus encore lorsque vous stockez une valeur ayant un fuseau horaire connu. Le type 'datetime' ressemble beaucoup à une chaîne de nombres condensés. Il n'y a pas de détails de fuseau horaire stockés avec cela.
Le type 'date' est généralement bon à utiliser. Sachez cependant que dans certains contextes, il sera interprété comme une date/heure à minuit (du fuseau horaire actif), ce qui entraînera toutes les confusions liées à la "date/heure" que vous devriez éviter.
Pour toute valeur date-heure côté application, utilisez un 'int unsigned', un 'bigint' (signé), un 'double' (signé) ou un décimal (N, P), pour simplement stocker UNIX-Epoch-deltas . Assurez-vous d'afficher la résolution dans un suffixe de nom de colonne, s'il ne s'agit pas de secondes.
Exemples:
`mysql_row_created_at` TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
`mysql_row_updated_at` TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`Epoch` int unsigned NOT NULL,
`Epoch_ms` bigint NOT NULL,
`Epoch_us` bigint NOT NULL,
`Epoch` double NOT NULL,
`Epoch6` decimal(16,6),
Traitez votre base de données autant que le stockage idiot que possible. Par conséquent, effectuez uniquement des conversions côté application, jamais côté base de données.
Bon à savoir sur:
SELECT @@GLOBAL.TIME_ZONE
, @@SESSION.TIME_ZONE
, @@SESSION.TIMESTAMP
, UNIX_TIMESTAMP(NOW(6))
;