Cet article vous présentera l'utilisation de la précision d'horodatage 1901 dans MySQL. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.
Pourquoi la précision DATETIME dans MySQL ne prend-elle en charge que les secondes ?
Le type DATETIME dans MySQL est-il lié au fuseau horaire ?
Lors de la conception d'une table dans MySQL, comment choisir le champ représentant l'heure ?
Analyse de cas de problèmes de précision DATETIME
Il y a quelque temps, la version de mysql-connector-java de l'application responsable a été mise à niveau de 5.1.16 à 5.1.30, et j'ai découvert quand En effectuant une régression de fonction, les données d'exécution des cas d'utilisation similaires au SQL ci-dessus seront manquantes, ce qui entraînera des problèmes fonctionnels.
Considérant que dans l'application dont je suis responsable, il existe une fonction qui nécessite l'utilisation de SQL similaire à la suivante, c'est-à-dire utiliser l'horodatage comme condition de requête pour interroger toutes les données après un certain horodatage.
Après enquête, il a été constaté que mysql-connector-java rejetait la précision quelques secondes avant la version 5.1.23, puis la transmettait au serveur MySQL, ce qui s'est avéré être dans la version MySQL que nous avons utilisée, la précision de DATETIME est en secondes ; après la mise à niveau de mysql-connector-java vers 5.1.30, lorsque l'horodatage est transmis de l'application Java au serveur MySQL via mysql-connector-java, les millisecondes seront ne doit pas être écarté du point de vue de mysql-connector-java, cela corrige un BUG, mais pour mon application, cela déclenche un BUG.
Si vous êtes confronté à ce problème, comment le résoudriez-vous ?
Nous avons pensé à trois options à l'époque :
Changer le type de paramètre d'horodatage dans l'interface Mapper de mybatis de java.util.Date à java.sql.Date
Avant de passer à l'interface Mapper, l'horodatage entrant est corrigé par secondes. Le code est le suivant
Avant l'interrogation, l'horodatage entrant est décrémenté de 1 seconde ; 🎜>
Après vérification, la solution 1 sera que l'objet java.sql.Date converti à partir de java.util.Date perdra toute la précision après la date, ce qui entraînera l'interrogation de davantage de données inutiles, mais la solution 3 est possible ; une ou deux données supplémentaires peuvent être trouvées ; l'option 2 est également possible, ce qui équivaut à compenser les caractéristiques de mysql-connector-java en termes de code. Finalement, j'ai choisi l'option 2. Reproduction du casUtilisez homebrew pour installer MySQL. La version est 8.0.15. Après l'installation, créez une table pour stocker les informations utilisateur. Utilisez spirngboot + mybatis comme framework de développement, définissez une entité utilisateur, le code est le suivant : Définissez le Mapper correspondant à cette entité, le code est le suivant : Définir la configuration liée à la connexion à mysql, le code est le suivant : Écrivez le code de test, insérez d'abord une donnée, puis utilisez l'horodatage comme condition de requête pour interroger. Le code est le suivant : . Lors de l'exécution d'un seul test, comme nous l'avions imaginé, aucune donnée n'a été interrogée. Les résultats sont les suivants :Modifiez ensuite le code et utilisez le code ci-dessus pour corriger l'horodatage de la requête. par secondes. Le code est le suivant : Réexécuter un seul test, comme nous l'imaginions, les données peuvent être interrogées cette fois. Cependant, voici un petit épisode Lorsque j'ai conçu la table pour la première fois, l'instruction SQL que j'ai utilisée était la suivante, Intelligent comme vous l'êtes. J'ai dû découvrir que le datetime ici prend déjà en charge une précision temporelle plus petite après la virgule décimale. Il prend en charge jusqu'à 6 chiffres, c'est-à-dire qu'il peut prendre en charge jusqu'au niveau microscopique. Quand cette fonctionnalité a-t-elle été introduite ? J'ai vérifié la [documentation officielle de MySQL][9] et j'ai découvert que cette fonctionnalité était prise en charge après MySQL 5.6.4. Résumé des points de connaissances
Après l'analyse précédente du cas réel et la récurrence du cas, les lecteurs doivent avoir une certaine compréhension du type DATETIME dans MySQL. Voyons ensuite quelles expériences nous pouvons résumer à partir de ce cas.
La version de mysql-connector-java et la version de mysql doivent être utilisées ensemble. Par exemple, pour les versions antérieures à 5.6.4, il est préférable de ne pas utiliser les versions antérieures à 5.1.23 de mysql-connector. -java, sinon il pourrait rencontrer les problèmes que nous avons rencontrés cette fois.
Les types de champs utilisés pour représenter l'heure dans MySQL sont : DATE, DATETIME et TIMESTAMP. Ils ont des similitudes et chacun a ses propres caractéristiques. J'ai résumé un tableau comme suit :
Le type DATETIME est stocké dans MySQL sous forme d'entier au format "AAAAMMJJHHMMSS", quel que soit le fuseau horaire, en utilisant 8 octets d'espace Le type TIMESTAMP peut être enregistré La plage horaire est ; beaucoup plus petit et la valeur affichée dépend du fuseau horaire. Le serveur MySQL, le système d'exploitation et la connexion client ont tous des paramètres de fuseau horaire. Généralement, il est recommandé d'utiliser DATETIME comme champ d'horodatage, et il n'est pas recommandé d'utiliser le type bigint pour stocker l'heure. Pendant le développement, vous devez essayer d'éviter d'utiliser des horodatages comme conditions de requête. Si vous devez les utiliser, vous devez pleinement prendre en compte l'exactitude de MySQL et l'exactitude des paramètres de requête. Apprentissage recommandé :Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!