Comment stockez-vous les "dates floues" dans une base de données?

125

C'est un problème que j'ai rencontré plusieurs fois. Imaginez que vous ayez un enregistrement que vous souhaitez stocker dans une table de base de données. Cette table a une colonne DateTime appelée "date_created". Cet enregistrement en particulier a été créé il y a longtemps et vous n'êtes pas vraiment sûr de la date exacte, mais vous connaissez l'année et le mois. Autres disques que vous connaissez juste l'année. Autres enregistrements vous connaissez le jour, le mois et l'année.

Vous ne pouvez pas utiliser un champ DateTime, car "mai 1978" n'est pas une date valide. Si vous le divisez en plusieurs colonnes, vous perdez la possibilité d'interroger. Quelqu'un d'autre a-t-il rencontré cela? Si oui, comment l'avez-vous géré?

Pour clarifier le système que je suis en train de construire, c'est un système de suivi des archives. Certains contenus ont été produits il y a longtemps et tout ce que nous savons, c'est "mai 1978". Je pourrais le stocker comme le 1er mai 1978, mais seulement avec un moyen de noter que cette date n’est précise que pour le mois. Ainsi, quelques années plus tard, lorsque je récupèrerai ces archives, je ne serai pas confus lorsque les dates ne correspondent pas.

Pour mes besoins, il est important de différencier "jour inconnu de mai 1978" du "1er mai 1978". De plus, je ne voudrais pas stocker les inconnus comme 0, comme "0 mai 1978", car la plupart des systèmes de base de données refusent cela comme une date non valide.

nbv4
la source
14
Est-il important de différencier "jour inconnu de mai 1978" du "1er mai 1978"?
5
@MichaelT: oui, il est important de faire la différence.
nbv4
6
@aslum: la plupart des systèmes de base de données vont rejeter cela comme une valeur de date invalide
nbv4
9
@ JimmyHoffa - vous n'êtes jamais tombé sur un scénario de dates flou, ni de scénario où vous deviez comparer des dates? Dans les deux cas, l’histoire médicale est commune: rappelez-vous que l’appendicectomie a eu lieu l’année dernière le 1 er avril, mais que l’amygdalectomie a eu lieu en 1975 et que quelque chose d’autre s’est passé en mai et juin. Et si vous voulez savoir si un événement médical a eu lieu avant ou après une autre percée médicale? Est-ce que cela est arrivé avant ou après qu'ils aient vérifié les réserves de sang pour le VIH?
jeudi

Réponses:

148

Stockez toutes les dates dans le champ DATE normal de la base de données et disposez d’un champ d’exactitude supplémentaire pour indiquer le degré de précision du champ DATE.

date_created DATE,
date_created_accuracy INTEGER, 

date_created_accuracy: 1 = date exacte, 2 = mois, 3 = année.

Si votre date est floue (par exemple, mai 1980), stockez-la au début de la période (par exemple, le 1er mai 1980). Ou si votre date est exacte à l'année (par exemple 1980), stockez-la le 1er janvier. 1980 avec la valeur de précision correspondante.

De cette façon, vous pouvez facilement interroger de manière assez naturelle et avoir toujours une idée de la précision des dates. Par exemple, cela vous permet d'interroger des dates entre Jan 1st 1980et Feb 28th 1981, et d'obtenir des dates 1980et May 1980.

Juha Syrjälä
la source
1
Il me reste à calculer la date-fin ici à partir de ce que je peux voir. Je pense donc qu'entre les requêtes est assez moche, car vous avez au mieux un champ calculé que vous sélectionnez.
Wyatt Barnett
8
Bonne réponse, vraiment intelligent. select * from mytable where date_created between "1980/1/1" and "1981/2/28" and date_created_accuracy <= 2;. Génie.
Naftuli Kay
58
Je vous encourage à considérer la précision de la date comme un simple "jour". Où un jour exact est 0. De cette façon, on peut utiliser des dates plus flexibles "Quelque temps en été" avec une précision de date de 90 jours basée sur le 1er juin plutôt que des plages de dates codées en dur. Il pourrait également gérer une précision pluriannuelle.
1
Vous devriez peut-être soumettre cela comme réponse, MichaelT
Supr
1
+1: Une autre bonne chose à propos de cette solution est que vous pouvez ensuite ajouter une logique d'affichage basée sur la valeur du date_created_accuracychamp. Vous pouvez afficher "mai 1980" ou simplement "1980" dans les résultats ou dans l'interface utilisateur si cela est aussi précis que le champ l'indique.
Kyralessa
27

Si vous n'avez pas besoin d'utiliser ce type de données comme information de date / heure normale, n'importe quel format de chaîne suffirait.

Mais si vous devez conserver toutes les fonctionnalités, il existe deux solutions de contournement auxquelles je peux penser, qui nécessitent toutes les deux des informations supplémentaires stockées dans la base de données:

  1. Créez min dateet les max datechamps, qui ont des valeurs différentes pour les données "incomplètes", mais coïncident pour des dates précises.
  2. Créez des types pour chaque type de date inexacte (aucun _ 0, date_missing _ 1, mois_missing _ 2, année_missing_4, etc. _ afin que vous puissiez les combiner). Ajoutez un typechamp aux enregistrements et conservez les informations manquantes.
superM
la source
Les champs de date min et max étaient aussi ma première pensée.
Michael Itzoe
1
Il y a longtemps, nous avons dû résoudre exactement le même problème. Les utilisateurs pouvaient raconter des histoires d'événements qui se produisaient n'importe quand dans le passé. Nous devions donc supporter les dates floues. Après beaucoup de va-et-vient, la solution à laquelle nous sommes arrivés est très similaire à la suggestion de superM ici, où les dates sont stockées en tant qu'instants min et max possibles pouvant contenir la date de l'histoire. Lors de la déclaration de la date, l’exactitude (c’est-à-dire "cet enregistrement est conforme au mois / année / jour") peut être extraite du delta entre les dates minimum et maximum. Pas besoin de stocker un 3ème champ pour plus de précision.
meetamit
4
+1 pour min dateet max datechamps. Je pense que c'est la solution la plus flexible, mais précise et facile à utiliser.
Supr
1
Au début, j'étais opposé à cette idée. Mais réalisant que c'est l'approche la plus flexible, je vote pour cela.
Anurag Kalia
C'est naturel. Vous décrivez moins une date floue qu'un calendrier ... qui a un début et une fin.
Pieter B
20

Il s’agit en réalité d’une définition d’exigences plutôt que d’un problème technique: vous devez vous concentrer sur "comment définir les dates antérieures" et la solution technique va suivre.

Les fois où j'ai dû aborder quelque chose comme ça, nous avons généralement:

  • Définissez comment mapper les éléments - comme le suggère MichaelT - , décidez que tout ce qui est défini comme Mois / Jour devient défini comme minuit le premier jour dudit mois. C’est généralement suffisant dans la plupart des cas - si la date exacte était si importante, vous en auriez probablement la trace 35 ans plus tard, non?
  • Déterminez si vous devez suivre cela - IE, les enregistrements avec des dates de création légèrement inventées ont-ils besoin d'un indicateur? Ou s'agit-il simplement d'un problème de formation des utilisateurs afin que les utilisateurs sachent qu'ils puissent agir en conséquence?

Parfois, il faut faire quelque chose comme rendre les dates floues - par exemple, une date peut avoir besoin de répondre à une requête pour quoi que ce soit en mai 1978. Cela est faisable - il suffit de créer vos champs create_date 2, les anciens enregistrements obtiennent un 30 les jours sont répartis comme il convient, les nouveaux ont 2 valeurs identiques.

Wyatt Barnett
la source
1
+1 - Je travaillais sur la formulation d'une réponse avec l'approche de la double date. Votre réponse est arrivé ici en premier.
2
+1, c'est moche et crée beaucoup d'informations supplémentaires inutiles pour les nouvelles entrées qui n'en ont pas besoin, mais d'un autre côté, les requêtes sont beaucoup plus simples qu'elles ne le seraient autrement. Nous utilisons une solution similaire pour un problème connexe depuis un certain temps maintenant.
Izkata
3
@Izkata - C'est juste, mais à quel point pouvez-vous être élégant lorsque vous devez créer quelque chose qui devrait être un mois dans un seul moment? Certainement plus agréable que de devoir calculer le début et la fin des requêtes à la volée quelque part.
Wyatt Barnett
1
+1 pour pouvoir indiquer une granularité arbitraire sans explosion des valeurs enum.
Dan Neely
18

Le moyen le plus simple d'indiquer si la date est exacte consiste à créer un champ de précision INT (1) avec la valeur NULL par défaut.

Si la date est exacte, stockez la date et l'heure dans "date_created" et laissez la précision à NULL

Si la date n’est précise que pour le mois, stockez la date et l’heure au 1er du mois avec la valeur de précision 1

Si la date n’est exacte que pour l’année, date-heure du magasin, le 1er janvier, avec la valeur d’exactitude 2

Vous pouvez utiliser différents nombres pour contenir différentes valeurs telles que premier trimestre, etc.

david strachan
la source
Les requêtes deviennent vraiment velues quand vous faites cela.
Blrfl
3
Cela pose des problèmes avec des données qui ne se situent pas dans une limite de mois vierge, telles que "Q2 1991" et "Hiver 1978-1979".
1
OP veut pouvoir indiquer que cette date est exacte au mois.
David Strachan
7
Vous abusez du sens de NULL ici. NULL signifie "inconnu", donc si la date est exacte, la précision ne peut pas être NULL. Il peut être '1'.
Konerak
@ Konerak sémantiquement oui. Mais comme la majorité des dates sont exactes, seuls les cas spéciaux doivent être identifiés et utiliser NULL ici par défaut.
David Strachan
17

Dans le passé, j’enregistrais des dates avec précision comme date de début et de fin. Le jour du 21 mai 2012 serait représenté par le début = 12h, le 21 mai 2012 et la fin = 12h, le 22 mai 2012. L'année 2012 serait représentée par le début = 12 h, le 1 janvier 2012 et fin = 12 h, le 1 janvier 2013.

Je ne sais pas si je recommanderais cette approche. Lorsque vous affichez les informations à l'utilisateur, vous devez détecter correctement qu'une plage de dates couvre exactement un jour afin d'afficher le "25 mai" au lieu de deux points de terminaison trop spécifiques (ce qui signifie que vous devez gérer l'heure d'été, etc.).

Cependant, lorsque vous n'essayez pas de traduire en humain, la programmation avec les points de terminaison est beaucoup plus facile qu'avec centre + précision. Vous ne vous retrouvez pas avec beaucoup de cas. C'est plutôt sympa.

Craig Gidney
la source
En fait, il n’est pas nécessaire que ce soit si difficile de déterminer comment présenter une plage si celle-ci est toujours stockée au format UTC. Comme les horodatages UTC, chaque jour, semaine, mois, année - même les saisons et les trimestres - aura deux nombres constants, globaux, distincts et facilement déterminables représentant le début et la fin de la période. La logique devient simplement quelques if-instructions pour voir si les deux dates sont au début et à la fin d'une période. Pas besoin de calculs compliqués ni de fuseau horaire :)
Supr
@Supr Déterminer si une seconde particulière se trouve à la frontière d'une période humaine particulière est en soi un problème difficile. Surtout à long terme, avec le ralentissement de la rotation de la Terre et la modification sans fin de la définition du temps local par l'homme.
Craig Gidney
14

Pourquoi ne pas stocker deux dates.

Created_After et Created_Before. La sémantique réelle étant "créée le ou après" et "créée le ou avant"

Donc, si vous connaissez la date exacte, Created_After et Created_Before sera la même date.

Si vous savez que c'était la première semaine de mai 2000, Created_After = '2000-05-01' et Created_Before = '2000-05-07'.

Si vous savez simplement que mai 1999, les valeurs seront '1999-05-01' et '1999-05-30'.

Si c'est "l'été de '42", les valeurs seront "1942-06-01" et "1942-08-31".

Ce schéma est simple à interroger avec du SQL normal et assez facile à suivre pour un utilisateur non technique.

Par exemple, pour trouver tous les documents pouvant avoir été créés en mai 2001:

SELECT * FROM DOCTAB WHERE Created_After < '2001-05-31' And Created_Before > 2001-05-01;

Inversement, vous trouverez tous les documents définitivement créés en mai 2001:

SELECT * FROM DOCTAB WHERE Created_After > '2001-05-01' And Created_Before < 2001-05-31;
James Anderson
la source
1
Je pense que c'est la solution la plus élégante.
Pieter B
Ceci est identique aux réponses de superM et de Strilanc. +1 pour expliquer plus clairement et montrer à quel point il est simple d'interroger.
Supr
9

Le format date / heure ISO 8601 est fourni avec une définition de la durée, par exemple:

2012-01-01P1M (lire: 1er janvier 2012, période: 1 mois) est ce qui devrait être «en janvier 2012».

Je voudrais utiliser cela pour stocker les données. Pour ce faire, vous aurez peut-être besoin d'un champ de base de données de type String. C'est une autre question de savoir comment mener une recherche judicieuse à ce sujet.

Matthias Ronge
la source
+1 pour l'idée mais -1 pour ne pas utiliser un champ de date pour la raison de la recherche et / ou de la recherche
user151019
Dépend de la base de données. Cependant, cela peut être une base d'expansion, mais la question est la suivante: le document est-il défini dans le résultat si vous recherchez, dans ce cas, tous les documents plus récents que le 12 janvier, ou non? Ce n'est pas trivial. Ici, la question était de savoir comment stocker les dates floues.
Matthias Ronge
3

Généralement, je les stocke toujours en tant que dates de requête générales, même si elles sont légèrement moins précises.

S'il est important de connaître la précision, j'ai stocké une "fenêtre" de précision sous forme de décimale +/- ou de recherche (jour, mois, année, etc.). Dans d'autres cas, au lieu de la fenêtre, je stocke simplement la valeur de date d'origine sous forme de chaîne et convertis ce que je peux en date / heure, éventuellement 1978-05-01 00:00:00 et "mai 1978" pour votre exemple donné.

Facture
la source
3

Si vous le divisez en plusieurs colonnes, vous perdez la possibilité d'interroger.

Dit qui? Voici ce que vous faites:

  1. Avoir 3 colonnes, Jour, Mois, Année, chacun de type int et une quatrième colonne de type Date de DateTime.
  2. Ayez un déclencheur qui utilise les 3 colonnes Jour, Mois, Année pour construire TheDate si TheDate est laissé à null, mais un ou plusieurs champs Day, Month, Year ont une valeur.
  3. Avoir un déclencheur qui remplit les champs Jour, Mois, Année lorsque TheDate est fourni mais que ces champs ne le sont pas.

Donc, si je fais un insert comme: insert into thistable (Day, Month, Year) values (-1, 2, 2012);alors TheDate deviendra le 01/02/2013, mais je saurai que c'est vraiment une date indéterminée dans 2/2012 en raison du -1 dans le champ Jour.

Si je suis insert into thistable (TheDate) values ('2/5/2012');alors jour sera 5, mois sera 2 et année sera 2012 et parce qu'aucun d'entre eux n'est -1 je saurai que c'est la date exacte.

Je ne perds pas la possibilité d'interroger car le déclencheur d'insertion / de mise à jour garantit que mes 3 champs (Jour, Mois, Année) produisent toujours une valeur DateTime dans TheDate qui peut être interrogée.

ordure
la source
3

Une autre option consisterait à stocker les dates sous forme d’entiers du formulaire YYYYMMDD.

  • Vous savez seulement que l'année est 1951: Store as 19510000
  • Vous savez que le mois et l’année sont en mars 1951: Store as 19510300
  • Vous savez que la date complète est le 14 mars 1951: Store as 19510314
  • Une date complètement inconnue: Store as 0

Avantages

Vous pouvez stocker votre date floue dans un champ au lieu de deux, ou une date et une précision comme le suggèrent de nombreuses autres réponses.

Les requêtes sont toujours faciles:

  • tous les records pour l'année 1951 - SELECT * FROM table WHERE thedate>=19510000 and thedate<19520000
  • tous les records pour mars 1951 - SELECT * FROM table where thedate>=19510300 and thedate<19510400
  • tous les documents du 14 mars 1951 - SELECT * FROM table where thedate=19510314

REMARQUES

  • Votre interface graphique aurait besoin d’une interface GetDateString(int fuzzyDate)facile à mettre en œuvre.
  • Le tri est facile avec le format int. Vous devez savoir que les dates inconnues viendront en premier. Vous pouvez inverser cela en utilisant 99pour le 'padding' au lieu du 00mois ou du jour.
Rick
la source
Comment représentez-vous la date floue de "l'hiver 1941-1942"? Ce pourrait être décembre 1941 ou janvier 1942.
1
Votre question concerne un cas de solution générale. La question initiale ne mentionne pas cela comme un problème. Sur la base de la question affichée, la date complète est parfois connue, parfois uniquement l'année et le mois, et parfois uniquement l'année. Aucune question de plage de dates floue n'est mentionnée comme une exigence. Je conviendrais que vous avez besoin de deux dates si vous aviez besoin de résoudre ce problème (bien que, stocker la plage sous deux "entrées de date floues" pourrait fournir plus de flexibilité que de stocker deux dates "dures").
Rick
1

L'ISO 8601 spécifie également une syntaxe pour les "dates floues". Le 12 février 2012 à 15 heures serait "2012-02-12T15" et février 2012 pourrait être simplement "2012-02". Cela s'étend bien en utilisant le tri lexicographique standard:

$ (echo "2013-03"; echo "2013-03"; echo "2012-02-12T15"; echo "2012-02"; echo "2011") | sort
2011
2012
2012-02
2012-02-12T15
2013-03
Une réponse
la source
0

Voici mon point de vue sur ceci:

Passer de la date floue à l'objet datetime (qui s'intégrera dans une base de données)

import datetime
import iso8601

def fuzzy_to_datetime(fuzzy):
    flen = len(fuzzy)
    if flen == 4 and fuzzy.isdigit():
        dt = datetime.datetime(year=int(fuzzy), month=1, day=1, microsecond=111111)

    elif flen == 7:
        y, m = fuzzy.split('-')
        dt = datetime.datetime(year=int(y), month=int(m), day=1, microsecond=222222)

    elif flen == 10:
        y, m, d = fuzzy.split('-')
        dt = datetime.datetime(year=int(y), month=int(m), day=int(d), microsecond=333333)

    elif flen >= 19:
        dt = iso8601.parse_date(fuzzy)

    else:
        raise ValueError("Unable to parse fuzzy date: %s" % fuzzy)

    return dt

Et ensuite une fonction qui prend l'objet datetime et le ramène à une date floue.

def datetime_to_fuzzy(dt):
    ms = str(dt.microsecond)
    flag1 = ms == '111111'
    flag2 = ms == '222222'
    flag3 = ms == '333333'

    is_first = dt.day == 1
    is_jan1 = dt.month == 1 and is_first

    if flag1 and is_jan1:
        return str(dt.year)

    if flag2 and is_first:
        return dt.strftime("%Y-%m")

    if flag3:
        return dt.strftime("%Y-%m-%d")

    return dt.isoformat()

Et puis un test unitaire. Ai-je oublié des cas?

if __name__ == '__main__':
    assert fuzzy_to_datetime('2001').isoformat() == '2001-01-01T00:00:00.111111'
    assert fuzzy_to_datetime('1981-05').isoformat() == '1981-05-01T00:00:00.222222'
    assert fuzzy_to_datetime('2012-02-04').isoformat() == '2012-02-04T00:00:00.333333'
    assert fuzzy_to_datetime('2010-11-11T03:12:03Z').isoformat() == '2010-11-11T03:12:03+00:00'

    exact = datetime.datetime(year=2001, month=1, day=1, microsecond=231)
    assert datetime_to_fuzzy(exact) == exact.isoformat()

    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=1, day=1, microsecond=111111)) == '2001'
    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=3, day=1, microsecond=222222)) == '2001-03'
    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=6, day=6, microsecond=333333)) == '2001-06-06'

    assert datetime_to_fuzzy(fuzzy_to_datetime('2002')) == '2002'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2002-05')) == '2002-05'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2002-02-13')) == '2002-02-13'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2010-11-11T03:12:03.293856+00:00')) == '2010-11-11T03:12:03.293856+00:00'

Il existe un cas particulier dans lequel un événement s'est produit exactement à 2001-01-01T00:00:00.333333mais le système sera interprété comme étant "2001", mais cela semble très improbable.

nbv4
la source
0

Je travaille pour une maison d'édition qui traite beaucoup de vieux livres où nous ne pouvons souvent pas obtenir les dates exactes. Nous avons généralement deux champs pour une entrée de date donnée, la date et vers booléenne:

date date
dateCirca enum('Y', 'N')

Nous utilisons le champ de date pour indiquer la date d’un événement ou une date "suffisamment proche" dans le cas où nous ne connaissons pas la date vraie. Si nous ne connaissons pas la date vraie, nous marquons le dateCircachamp comme Yet donnons une date assez proche, qui est marquée comme "1er", comme par exemple

1st March, 2013  // We don't know the day of the month
1st January, 2013  // We don't know the month/day of the year
1st January, 2000  // We don't know the month/day/year, we only know the century
utilisateur7007
la source
0

Vue d'ensemble

Il existe de nombreuses représentations possibles, et donc des schémas de base de données, permettant de stocker des dates-heures floues (ou même simplement des dates floues):

  1. Date-heure et code indiquant sa précision ou exactitude
  2. Date-heure et intervalle où il y a plusieurs possibilités pour représenter un intervalle:
    1. Représente tous les intervalles sous forme de nombre entier (ou autre nombre) d'une unité fixe, par exemple jours, minutes, nanosecondes.
    2. Représente un intervalle sous la forme d'un nombre entier (ou d'un autre nombre) et d'un code indiquant ses unités.
  3. Heures de début et de fin
  4. Chaîne
  5. Distribution de probabilité:
    1. Quantités décimales ou à virgule flottante pour les paramètres spécifiant une distribution spécifique dans une famille particulière, par exemple, écart type et écart type d’une distribution normale.
    2. Fonction de distribution de probabilité, par exemple sous forme de code (de référence) (éventuellement avec des paramètres de valeurs spécifiques), ou sous forme d'expression dans un langage, un format ou une représentation suffisamment expressif.

[1], [2] et [3] sont tous (implicitement) des intervalles uniformes, c'est-à-dire un ensemble de points dans le temps (égaux).

[4] est le plus expressif, c’est-à-dire lorsqu’il permet des phrases ou des expressions écrites possibles (ou du moins arbitrairement longues). Mais c'est aussi le plus difficile à travailler. À la limite, une IA au niveau humain serait nécessaire pour gérer des valeurs arbitraires. Pratiquement, la plage de valeurs possibles devrait être sévèrement restreinte et des valeurs «structurées» alternatives seraient probablement préférées pour de nombreuses opérations, telles que le tri, la recherche.

[5] est probablement la représentation compacte la plus générale qui soit (un peu) pratique.

Intervalles uniformes

Les intervalles uniformes constituent le moyen le plus simple et le plus simple de représenter un ensemble de valeurs (possibles) date-heure.

Pour [1], les parties de la valeur date-heure sont ignorées, c'est-à-dire les parties correspondant à des unités plus fines que la précision ou l'exactitude indiquée. sinon, cela équivaut à [2] et le code précision / exactitude est équivalent à un intervalle avec les mêmes unités (et une quantité implicite de 1).

[2] et [3] sont expressément équivalents. [1] est strictement moins expressif que l'un ou l'autre puisqu'il existe des intervalles efficaces qui ne peuvent pas être représentés par [1], ex. une date-heure floue équivalente à un intervalle de 12 heures couvrant une limite de date.

[1] est plus facile à saisir pour les utilisateurs que toute autre représentation et devrait généralement nécessiter (au moins légèrement) moins de dactylographie. Si les dates peuvent être entrées dans différentes représentations textuelles, par exemple "2013", "2014-3", "2015-5-2", "30/07/2016 11p", "2016-07-31 18:15" , la précision ou l'exactitude peut également être déduite automatiquement de l'entrée.

L’exactitude ou la précision de [1] est également plus facile à convertir en un formulaire à transmettre aux utilisateurs, par exemple «2015-2015 avec l’exactitude mensuelle» en «mai 2015», par opposition à «13 mai 2015 2p, plus ou moins 13,5 jours». (notez que ce dernier ne peut de toute façon pas être représenté par [1]).

Les cordes

Dans la pratique, les valeurs de chaîne devront être converties en d'autres représentations pour interroger, trier ou comparer plusieurs valeurs. Ainsi, alors que tout langage naturel (humain) écrit est strictement plus expressif que [1], [2], [3] ou [5], nous n'avons pas encore les moyens de gérer beaucoup plus que des représentations ou des formats de texte standard. Compte tenu de cela, c'est probablement la représentation la moins utile en soi .

L'un des avantages de cette représentation est que les valeurs doivent, dans la pratique, être présentées aux utilisateurs tels quels et ne pas nécessiter de transformation pour être facilement compréhensibles.

Distributions de probabilité

Les distributions de probabilité généralisent les représentations d'intervalle uniforme [1], [2], [3] et (sans doute) sont équivalentes à la représentation (générale) sous forme de chaîne [4].

L'un des avantages des distributions de probabilités par rapport aux chaînes est que les premières sont sans ambiguïté.

[5-1] conviendrait pour des valeurs qui (le plus souvent) sont conformes à une distribution existante, par exemple une valeur date-heure générée par un appareil pour lequel les mesures sont connues (ou supposées) se conformer à une distribution spécifique.

[5-2] est probablement le meilleur moyen (un peu) pratique de représenter de manière compacte des valeurs arbitraires de type "date floue". Bien sûr, la calculabilité des distributions de probabilité spécifiques utilisées est importante et il existe certainement des problèmes intéressants (et peut-être impossibles) à résoudre lors de l'interrogation, du tri ou de la comparaison de valeurs différentes, mais la plupart de ces problèmes sont probablement déjà connus ou résolus quelque part dans le système existant. dans la littérature mathématique et statistique, il s’agit donc d’une représentation extrêmement générale et non ambiguë.

Kenny Evitt
la source
-1

J'aime beaucoup la solution de James Anderson - La délimitation précise des dates est le moyen d'obtenir la structure de requête la plus flexible. Une autre façon de réaliser la même chose consiste à utiliser un début, une fin ou même un centre dateplus un interval(disponible au moins dans PostgreSQL , Oracle et SQLAlchemy ).

l0b0
la source
-2

Dans votre cas, vous n'avez besoin que de l'année, du mois et du jour. L'année et le mois sont obligatoires, le jour est facultatif. J'utiliserais quelque chose comme ça:

year smallint not null,
month smallint not null,
day smallint

De plus, vous pouvez toujours utiliser les index très efficacement. Le (minuscule = moins, les queires deviennent un peu plus "compliqués" (plus longs).

Marin danubien
la source
1
Mais cela signifie que si le flou engloutit également la partie mois, cette approche échoue.
Anurag Kalia
1
@AnuragKalia - rend donc le champ de mois nullable. Aucune raison pour que cela ne puisse pas être reconfiguré à une date ultérieure.
JeffO
C'était juste un exemple. La solution doit être suffisamment générale pour tenir compte des problèmes futurs. Si la plage que vous spécifiez va du 15 mars 2013 au 22 mars 2013, cette approche ne fonctionne pas. La réponse min-max ci-dessus est la plus générale à ce jour.
Anurag Kalia
1
Avez-vous trouvé une telle exigence dans les PO ou après c'est juste votre fantaisie?
Danubian Sailor
Rendre le mois nullable vous permet de spécifier un jour mais pas un mois. Cela n'a pas de sens non plus. Quand était 1978-??-31?
MSalters
-2

Je voudrais simplement stocker l'heure exacte pour les dates normales et rendre la partie heure de la date floue générique comme 00:00:00. Je voudrais ensuite faire toutes les dates floues le 1er du mois.

Lorsque vous interrogez, vous

  1. vérifier les plages de dates où l'heure est égale à 00:00:00 (floue)
  2. vérifier les plages de dates où l'heure n'est PAS égale à 00:00:00 (réelle)
  3. vérifier les dates mais ignorer la partie heure (combinée)

Il existe de meilleures solutions que cela, mais je déteste personnellement les métadonnées (données relatives à mes données). Il a juste l'habitude de perdre le contrôle après un certain temps.

Capitaine Kenpachi
la source
2
comment cela se passerait-il avec la date réelle ayant l'heure 00:00:00?
Gnat
Bien qu’il soit théoriquement possible d’ajouter une date réelle à cette heure, cela ne se produira pas. J'ai vu des tables avec des millions de lignes et aucune d'elles n'avait de valeur datetime où l'heure était 00:00:00. Le pragmatisme l'emporte sur la convention.
Capitaine Kenpachi