Je souhaite stocker les heures dans une table de base de données, mais je n'ai besoin que de stocker les heures et les minutes. Je sais que je pourrais simplement utiliser DATETIME et ignorer les autres composants de la date, mais quelle est la meilleure façon de le faire sans stocker plus d'informations que ce dont j'ai réellement besoin?
sql-server
database
database-design
datetime
Matthew Commode
la source
la source
Réponses:
Vous pouvez le stocker sous forme d'entier du nombre de minutes après minuit:
par exemple.
Il vous faudrait cependant écrire du code pour reconstituer l'heure, mais cela ne devrait pas être compliqué.
la source
Si vous utilisez SQL Server 2008+, tenez compte du
TIME
type de données. Article SQLTeam avec plus d'exemples d'utilisation.la source
Je vous implore d'utiliser à la place deux valeurs DATETIME , étiquetées quelque chose comme event_start et event_end .
Le temps est une affaire complexe
La plupart des pays du monde ont maintenant adopté le système métrique basé sur le denery pour la plupart des mesures, à tort ou à raison. C'est bien dans l'ensemble, car au moins nous pouvons tous convenir que ag, est un ml, est un cm cube. Du moins à peu près. Le système métrique a de nombreux défauts, mais au moins, il est systématiquement imparfait au niveau international.
Avec le temps cependant, nous avons; 1000 millisecondes dans une seconde, 60 secondes à une minute, 60 minutes à une heure, 12 heures pour chaque demi-journée, environ 30 jours par mois qui varient selon le mois et même l'année en question, chaque pays a son décalage horaire par rapport aux autres , la façon dont l'heure est formatée dans chaque pays varie.
C'est beaucoup à digérer, mais au bout du compte, il est impossible pour un scénario aussi complexe d'avoir une solution simple.
Certains coins peuvent être coupés, mais il y a ceux où il est plus sage de ne pas
Bien que la réponse principale ici suggère que vous stockez un nombre entier de minutes après minuit peut sembler parfaitement raisonnable, j'ai appris à éviter de le faire à la dure.
Les raisons d'implémenter deux valeurs DATETIME sont pour une augmentation de la précision, de la résolution et de la rétroaction.
Ceux-ci sont tous très pratiques lorsque la conception produit des résultats indésirables.
Est-ce que je stocke plus de données que nécessaire?
Il peut sembler initialement que plus d'informations sont stockées que ce dont j'ai besoin, mais il y a une bonne raison de prendre ce coup.
Stocker ces informations supplémentaires finit presque toujours par me faire gagner du temps et des efforts sur le long terme, car je constate inévitablement que lorsque quelqu'un est informé de la durée de quelque chose, il voudra également savoir quand et où l'événement a eu lieu.
C'est une énorme planète
Dans le passé, j'ai été coupable d'ignorer qu'il y a d'autres pays sur cette planète en dehors du mien. Cela semblait être une bonne idée à l'époque, mais cela a TOUJOURS entraîné des problèmes, des maux de tête et une perte de temps plus tard sur toute la ligne. Tenez toujours compte de tous les fuseaux horaires.
C #
Un DateTime se rend bien en une chaîne en C #. La méthode ToString (string Format) est compacte et facile à lire.
Par exemple
Serveur SQL
De plus, si vous lisez votre base de données séparément de l'interface de votre application, il est agréable de lire dateTimes en un coup d'œil et d'effectuer des calculs dessus est simple.
Par exemple
Norme de date ISO8601
Si vous utilisez SQLite, vous ne l'avez pas, alors utilisez plutôt un champ Texte et stockez-le au format ISO8601, par exemple.
"2013-01-27T12: 30: 00 + 0000"
Remarques:
Cela utilise une horloge de 24 heures *
La partie du décalage horaire (ou +0000) de l'ISO8601 correspond directement à la valeur de longitude d'une coordonnée GPS (sans tenir compte de l'heure d'été ou du pays).
Par exemple
... où ± fait référence à la direction est ou ouest.
Il vaut donc la peine de se demander s'il vaudrait la peine de stocker la longitude, la latitude et l'altitude avec les données. Cela variera en application.
ISO8601 est un format international.
Le wiki est très bon pour plus de détails à http://en.wikipedia.org/wiki/ISO_8601 .
La date et l'heure sont enregistrées dans l'heure internationale et le décalage est enregistré en fonction de l'endroit dans le monde où l'heure a été stockée.
D'après mon expérience, il est toujours nécessaire de stocker la date et l'heure complètes, que je pense qu'il y en ait ou non au début du projet. ISO8601 est une très bonne façon de le faire.
Conseils supplémentaires gratuits
Cela vaut également la peine de regrouper les événements comme une chaîne. Par exemple, si vous enregistrez une course, l'événement entier pourrait être regroupé par coureur, race_circuit, circuit_checkpoints et circuit_laps.
D'après mon expérience, il est également judicieux d'identifier qui a conservé l'enregistrement. Soit en tant que table séparée remplie via un déclencheur, soit en tant que colonne supplémentaire dans la table d'origine.
Plus vous en mettez, plus vous en sortez
Je comprends parfaitement le désir d'être aussi économique que possible avec l'espace, mais je le ferais rarement au détriment de la perte d'informations.
Une règle de base avec les bases de données est, comme le titre l'indique, qu'une base de données ne peut vous en dire autant qu'elle contient des données, et il peut être très coûteux de parcourir les données historiques, en comblant les lacunes.
La solution est de le corriger du premier coup. C'est certainement plus facile à dire qu'à faire, mais vous devriez maintenant avoir une idée plus approfondie de la conception efficace de la base de données et avoir par la suite une chance beaucoup plus grande de bien faire les choses du premier coup.
Plus votre conception initiale est bonne, moins les réparations seront coûteuses par la suite.
Je dis seulement tout cela, parce que si je pouvais remonter le temps, c'est ce que je me dirais en arrivant là-bas.
la source
Stockez simplement une date / heure normale et ignorez tout le reste. Pourquoi passer plus de temps à écrire du code qui charge un int, le manipule et le convertit en datetime, alors que vous pouvez simplement charger un datetime?
la source
DATETIME
type de données prend 4 octets à stocker, tandis qu'unSMALLINT
par exemple, n'en prend qu'un quart. Pas de grande différence si vous n'avez que quelques milliers de lignes, mais si vous avez plusieurs millions de lignes comme le font de nombreuses entreprises, alors vos économies d'espace seront substantielles.puisque vous ne l'avez pas mentionné un peu si vous êtes sur SQL Server 2008, vous pouvez utiliser le type de données time sinon utiliser les minutes depuis minuit
la source
SQL Server stocke en fait le temps sous forme de fractions de jour. Par exemple, 1 jour entier = valeur de 1. 12 heures est une valeur de 0,5.
Si vous souhaitez stocker la valeur d'heure sans utiliser de type DATETIME, stocker l'heure sous forme décimale répondra à ce besoin, tout en simplifiant la conversion en DATETIME.
Par exemple:
Le stockage de la valeur en tant que DECIMAL (9,9) consomme 5 octets. Cependant, si la précision n'est pas de la plus haute importance, un REAL ne consommera que 4 octets. Dans les deux cas, le calcul agrégé (c'est-à-dire le temps moyen) peut être facilement calculé sur des valeurs numériques, mais pas sur des types de données / temps.
la source
Je les convertirais en un entier (HH * 3600 + MM * 60) et les stockerais de cette façon. Petite taille de stockage, et toujours assez facile à utiliser.
la source
Si vous utilisez MySQL, utilisez un champ de type TIME et la fonctionnalité associée fournie avec TIME.
00:00:00 est le format d'heure UNIX standard.
Si jamais vous devez regarder en arrière et revoir les tableaux à la main, les entiers peuvent être plus déroutants qu'un horodatage réel.
la source
Essayez smalldatetime. Cela peut ne pas vous donner ce que vous voulez mais cela vous aidera dans vos futurs besoins en manipulations de date / heure.
la source
Êtes-vous sûr que vous n'aurez jamais besoin que des heures et des minutes? Si vous voulez faire quelque chose de significatif avec lui (comme par exemple calculer des intervalles de temps entre deux de ces points de données), ne pas avoir d'informations sur les fuseaux horaires et l'heure d'été peut donner des résultats incorrects. Les fuseaux horaires ne s'appliquent peut-être pas dans votre cas, mais l'heure d'été le fera certainement.
la source
Au lieu de minutes après minuit, nous le stockons au format 24 heures, en tant que SMALLINT.
09:12 = 912 14:15 = 1415
lors de la conversion en "forme lisible par l'homme", nous insérons simplement deux points ":" deux caractères à partir de la droite. Pavé gauche avec des zéros si vous en avez besoin. Enregistre les mathématiques dans chaque sens et utilise quelques octets de moins (par rapport à varchar), et garantit que la valeur est numérique (plutôt que alphanumérique)
Assez maladroit cependant ... il aurait dû y avoir un type de données TIME dans MS SQL depuis plusieurs années déjà à mon humble avis ...
la source
Ce que je pense que vous demandez, c'est une variable qui stockera les minutes sous forme de nombre. Cela peut être fait avec les différents types de variable entière:
Ensuite, dans votre programme, vous pouvez simplement afficher ceci sous la forme que vous souhaitez en calculant:
Un problème survient lorsque vous demandez que l'efficacité soit utilisée. Mais si vous manquez de temps alors utilisez simplement un BigInt nullable pour stocker la valeur de vos minutes.
Une valeur nulle signifie que l'heure n'a pas encore été enregistrée.
Maintenant, je vais l'expliquer sous la forme d'un aller-retour dans l'espace extra-atmosphérique.
Malheureusement, une colonne de table ne stockera qu'un seul type. Par conséquent, vous devrez créer une nouvelle table pour chaque type selon les besoins.
Par exemple:
Si MinutesInput = 0 .. 255 alors utilisez TinyInt (Convertissez comme décrit ci-dessus).
Si MinutesInput = 256 .. 131071, utilisez SmallInt (Remarque: la valeur minimale de SmallInt est -32 768. Par conséquent, annulez et ajoutez 32768 lors du stockage et de la récupération de la valeur pour utiliser la plage complète avant la conversion comme ci-dessus).
Si MinutesInput = 131072 .. 8589934591, utilisez alors Int (Remarque: annulez et ajoutez 2147483648 si nécessaire).
Si MinutesInput = 8589934592 .. 36893488147419103231, utilisez BigInt (Remarque: ajoutez et annulez 9223372036854775808 si nécessaire).
Si MinutesInput> 36893488147419103231, j'utiliserais personnellement VARCHAR (X) en augmentant X si nécessaire, car un caractère est un octet. Je devrai revoir cette réponse à une date ultérieure pour la décrire dans son intégralité (ou peut-être qu'un collègue stackoverflowee pourra terminer cette réponse).
Étant donné que chaque valeur nécessitera sans aucun doute une clé unique, l'efficacité de la base de données ne sera apparente que si la plage des valeurs stockées est un bon mélange entre très petite (proche de 0 minute) et très élevée (supérieure à 8589934591).
Jusqu'à ce que les valeurs stockées atteignent réellement un nombre supérieur à 36893488147419103231, vous pouvez également avoir une seule colonne BigInt pour représenter vos minutes, car vous n'aurez pas besoin de gaspiller un Int sur un identifiant unique et un autre int pour stocker la valeur des minutes.
la source
Le gain de temps au format UTC peut mieux aider, comme l'a suggéré Kristen.
Assurez-vous que vous utilisez une horloge de 24 heures car il n'y a pas de méridien AM ou PM être utilisé en UTC.
Exemple:
Il est toujours préférable d'utiliser le format standard à quatre chiffres.
la source
Stockez le
ticks
sous forme delong
/bigint
, qui sont actuellement mesurés en millisecondes. La valeur mise à jour peut être trouvée en regardant leTimeSpan.TicksPerSecond
valeur.La plupart des bases de données ont un type DateTime qui stocke automatiquement l'heure sous forme de graduations dans les coulisses, mais dans le cas de certaines bases de données, par exemple SqlLite, stocker des graduations peut être un moyen de stocker la date.
La plupart des langues permettent la conversion facile de
Ticks
→TimeSpan
→Ticks
.Exemple
En C #, le code serait:
Attention cependant, car dans le cas de SqlLite, qui ne propose qu'un petit nombre de types différents, qui sont;
INT
,REAL
etVARCHAR
Il sera nécessaire de stocker le nombre de graduations sous forme de chaîne ou de deuxINT
cellules combinées. En effet, anINT
est un nombre signé 32 bits alors queBIGINT
c'est un nombre signé 64 bits.Remarque
Ma préférence personnelle cependant serait de stocker la date et l'heure sous forme de
ISO8601
chaîne.la source
À mon humble avis, la meilleure solution dépend dans une certaine mesure de la façon dont vous stockez le temps dans le reste de la base de données (et le reste de votre application)
Personnellement, j'ai travaillé avec SQLite et j'essaie de toujours utiliser des horodatages unix pour stocker le temps absolu, donc lorsque je traite de l'heure de la journée (comme vous le demandez) je fais ce que Glen Solsberry écrit dans sa réponse et stocke le nombre de secondes depuis minuit
En adoptant cette approche générale, les gens (y compris moi!) Lisant le code sont moins confus si j'utilise le même standard partout
la source