Nous pouvons stocker les informations de date et d'heure de deux manières. Quelle est la meilleure approche pour stocker des informations DateTime?
Stocker la date et l'heure dans 2 colonnes séparées ou une colonne en utilisant DateTime ?
Pouvez-vous expliquer pourquoi cette approche est meilleure?
(Lien vers les documents MySQL pour référence, la question est générale, non spécifique à MySQL)
Types de date et d'heure : Date et heure
database-design
datetime
julien
la source
la source
date,time
avecgroup by date
mais pas pour un indexdatetime
avecgroup by cast(datetime as date)
même s'il fournira l'ordre souhaité.Réponses:
Le stockage des données dans une seule colonne est la méthode préférée, car elles sont inextricablement liées. Un point dans le temps est une seule information, pas deux.
Une façon courante de stocker des données de date / heure, employées "en arrière-plan" par de nombreux produits, est de les convertir en une valeur décimale où la "date" est la partie entière de la valeur décimale et le "temps" est la fraction valeur. Ainsi, 1900-01-01 00:00:00 est stocké en tant que 0.0 et le 20 septembre 2016 9:34:00 est stocké en tant que 42631.39861. 42631 est le nombre de jours depuis le 1900-01-01. .39861 est la partie du temps écoulé depuis minuit. N'utilisez pas de type décimal directement pour ce faire, utilisez un type de date / heure explicite; mon point ici est juste une illustration.
Le stockage des données dans deux colonnes distinctes signifie que vous devrez combiner les deux valeurs de colonne chaque fois que vous voulez voir si un moment donné est antérieur ou postérieur à la valeur stockée.
Si vous stockez les valeurs séparément, vous rencontrerez invariablement des "bogues" difficiles à détecter. Prenez par exemple ce qui suit:
Dans le code ci-dessus, nous créons une table de test, la remplissons avec deux valeurs, puis effectuons une requête simple sur ces données. La première
SELECT
renvoie les deux lignes, mais la secondeSELECT
ne renvoie qu'une seule ligne, ce qui peut ne pas être le résultat souhaité:La bonne façon de filtrer une plage de date / heure où les valeurs sont dans des colonnes discrètes, comme indiqué par @ypercube dans les commentaires, est:
Si vous avez besoin de séparer la composante temporelle à des fins d' analyse , vous pouvez envisager d'ajouter une colonne calculée et persistante pour la partie temporelle de la valeur:
La colonne persistante pourrait alors être indexée, ce qui permettrait des tri rapides, etc., par heure de la journée.
Si vous envisagez de diviser la date et l'heure en deux champs à des fins d'affichage, vous devez vous rendre compte que le formatage doit être effectué sur le client, pas sur le serveur.
la source
Je vais donner une opinion dissidente aux autres réponses.
Si les composants de date et d'heure sont requis ensemble, c'est-à-dire qu'une entrée n'est pas valide si elle contient l'un mais pas l'autre (ou est NULL dans l'un mais pas l'autre), alors le stockage dans une seule colonne est logique pour les raisons données dans d'autres réponses.
Cependant, il peut arriver qu'un ou les deux composants soient individuellement optionnels. Dans ce cas, il serait incorrect de le stocker dans une seule colonne. Cela vous obligerait à représenter les valeurs NULL de manière arbitraire, par exemple en stockant l'heure au format 00:00:00.
Voici quelques exemples:
Vous enregistrez les trajets en véhicule pour les déductions fiscales de kilométrage. Il serait utile de connaître l'heure exacte du voyage, mais si un employé ne l'a pas noté et l'a oublié, la date doit toujours être enregistrée par elle-même (date requise, heure facultative).
Vous menez une enquête pour savoir à quelle heure les gens mangent leur déjeuner et vous demandez aux participants de remplir un formulaire avec un échantillon de leurs heures de déjeuner, y compris les dates. Certains ne prennent pas la peine de remplir la date, et vous ne voulez pas supprimer les données car ce sont les heures qui vous intéressent vraiment (date facultative, heure requise).
Voir cette question connexe pour des approches alternatives.
la source
Je préfère toujours le stocker dans une seule colonne, sauf s'il existe une demande spécifique pour l'entreprise / l'application. Voici mes points -
la source
Dans SQL Server, il est préférable de stocker DataTime dans un seul champ. Si vous créez un index sur la colonne DataTime, il peut être utilisé comme recherche de date et comme recherche de date. Par conséquent, si vous devez limiter tous les enregistrements qui existent pour la date spécifique, vous pouvez toujours utiliser l'index sans rien faire de spécial. Si vous devez interroger la partie de l'heure, vous ne pourrez pas utiliser le même index et, par conséquent, si vous avez une analyse de rentabilisation où vous vous souciez plus de l'heure de la journée que de DateTime, vous devez la stocker séparément car vous devrez créer un index dessus et améliorer les performances.
la source
En effet, c'est dommage qu'il n'y ait pas de type de SGBD standard pour cela (comme INT et VARCHAR sont pour les entiers et les valeurs de chaîne). Les 2 approches de bases de données croisées que j'ai rencontrées jusqu'à présent utilisent des colonnes VARCHAR / CHAR pour stocker les valeurs DataTime sous forme de chaînes formatées selon la norme ISO 8601 (plus pratique, lisible par l'homme) et utilisent BIGINT pour les stocker en tant qu'horodatages POSIX (stockés plus efficace, plus rapide, plus facile à manipuler mathématiquement).
la source
timestamp
ce que définit le standard SQL. Stocker des horodatages sous forme de chaînes est un très mauvais conseilAprès avoir lu un tas de trucs, l'heure UTC Unix dans BIGINT semble être la solution optimale. TZDB timesone ID dans VARCHAR pour le stockage de fuseau horaire en cas de besoin. Quelques arguments:
TIMESTAMP et DATETIME font un tas de conversions gimmicky en arrière-plan qui semblent être complexes et pas claires. Le serveur passe de l'heure locale à l'heure UTC ou à l'heure du serveur et vice-versa, parfois ou non. Un tas de frais généraux cachés pour chaque fonction.
BIGINT (8 Ko) est au moins aussi léger ou plus léger que DECIMAL requis pour le stockage au format xxxxxx.xxxxxx, qui est pratiquement stocké sous la forme de deux INT + quelque chose par MySQL . Et c'est suffisant pour stocker les siècles à venir.
Presque tous les principaux langages de programmation ont des bibliothèques de fonctions standard pour fonctionner avec le temps Unix.
Les opérations mathématiques avec BIGINT devraient être aussi rapides ou plus rapides que toute autre chose sur n'importe quel matériel.
Bien sûr, tout ce qui précède est pertinent pour les grands projets internationaux. Pour quelque chose de petit, aller avec le format par défaut du cadre choisi semble être assez bon.
la source
timestamp
colonne, aucune "conversion gimmicky" ne se produit (au niveau de la couche de base de données) et pourtimestamp with time zone
cela, elle est bien documentée et expliquée dans les manuels (au moins pour Oracle et Postgres)