Come si memorizzano "date fuzzy" in un database?


125

Questo è un problema che ho riscontrato alcune volte. Immagina di avere un record che desideri archiviare in una tabella del database. Questa tabella ha una colonna DateTime chiamata "date_created". Questo particolare record è stato creato molto tempo fa e non sei davvero sicuro della data esatta, ma conosci l'anno e il mese. Altri record che conosci solo l'anno. Altri record che conosci il giorno, il mese e l'anno.

Non puoi utilizzare un campo DateTime, perché "Maggio 1978" non è una data valida. Se lo dividi in più colonne, perdi la possibilità di interrogare. Qualcun altro si è imbattuto in questo, se sì, come lo hai gestito?

Per chiarire il sistema che sto costruendo, è un sistema che tiene traccia degli archivi. Alcuni contenuti sono stati prodotti molto tempo fa e tutto ciò che sappiamo è "maggio 1978". Potrei memorizzarlo come 1 maggio 1978, ma solo con un modo per indicare che questa data è precisa solo per il mese. In questo modo alcuni anni dopo, quando sto recuperando quell'archivio, non sono confuso quando le date non coincidono.

Per i miei scopi, è importante differenziare "giorno sconosciuto nel maggio 1978" con "1 maggio 1978". Inoltre, non vorrei archiviare gli incogniti come 0, come "0 maggio 1978" perché la maggior parte dei sistemi di database lo rifiuterà come valore di data non valido.


14
È importante differenziare "giorno sconosciuto nel maggio 1978" con "1 maggio 1978"?

5
@MichaelT: sì, è importante differenziare.
nbv4,


6
@aslum: la maggior parte dei sistemi di database lo rifiuterà come valore di data non valido
nbv4

9
@JimmyHoffa: non ti sei mai imbattuto in uno scenario di date sfocate o in uno in cui dovevi confrontare le date? In entrambi i casi, una comune è una storia medica: ti ricordi che l'appendicectomia era lo scorso anno il 1 ° aprile, ma la tonsilectomia avvenne un po 'nel 1975, e qualcos'altro accadde tra maggio e giugno di qualche anno. Cosa succede se si desidera sapere se qualche evento medico è stato prima o dopo qualche altro progresso medico? È successo prima o dopo aver controllato le scorte di sangue per l'HIV?
giovedì giovedì

Risposte:


148

Memorizza tutte le date nel normale campo DATA nel database e dispone di un campo di precisione aggiuntivo per quanto preciso sia il campo DATA.

date_created DATE,
date_created_accuracy INTEGER, 

date_created_accuracy: 1 = data esatta, 2 = mese, 3 = anno.

Se la tua data è sfocata (ad es. Maggio 1980), memorizzala all'inizio del periodo (ad es. 1 maggio 1980). O se la tua data è precisa per l'anno (es. 1980) memorizzala come 1 gennaio. 1980 con corrispondente valore di precisione.

In questo modo puoi facilmente interrogare in modo un po 'naturale e avere ancora la nozione di date precise. Ad esempio, ciò consente di interrogare le date tra Jan 1st 1980e Feb 28th 1981e ottenere date sfocate 1980e May 1980.


1
Devi ancora calcolare la data di fine qui da quello che posso vedere, quindi penso che tra una query e abbastanza brutta in quanto hai un campo calcolato su cui stai selezionando al meglio.
Wyatt Barnett,

8
Bella risposta, davvero intelligente. select * from mytable where date_created between "1980/1/1" and "1981/2/28" and date_created_accuracy <= 2;. Genio.
Naftuli Kay

58
Ti incoraggio a considerare l'accuratezza della data semplicemente come "giorni". Dove un giorno esatto è 0. In questo modo è possibile utilizzare date più flessibili "A volte in estate" con una precisione della data di 90 giorni in base al 1 ° giugno anziché intervalli di date specifici codificati. Potrebbe anche gestire una precisione pluriennale.

1
Forse dovresti inviarlo come risposta, MichaelT
Supr

1
+1: Un'altra cosa bella di questa soluzione è che puoi aggiungere la logica di visualizzazione in base al valore del date_created_accuracycampo. Puoi mostrare "Maggio 1980" o semplicemente "1980" nei risultati o nell'interfaccia utente se questo è accurato come indica il campo.
Kyralessa,

27

Se non è necessario utilizzare questo tipo di dati come normali informazioni di data e ora, farebbe qualsiasi formato di stringa semplice.

Ma se hai bisogno di mantenere tutte le funzionalità, ci sono due soluzioni alternative che posso pensare, entrambe che richiedono ulteriori informazioni memorizzate nel database:

  1. Creare min datee max datecampi, che hanno valori diversi per i dati "incompleti", ma coincideranno con date precise.
  2. Crea tipi per ogni tipo di data imprecisa (nessuno _ 0, date_missing _ 1, month_missing _ 2, year_missing_4, ecc _ in modo da poterli combinare). Aggiungi un typecampo ai record e mantieni le informazioni mancanti.

Anche i campi con data minima e massima sono stati il ​​mio primo pensiero.
Michael Itzoe,

1
Molto tempo fa, abbiamo dovuto risolvere esattamente lo stesso problema. Gli utenti potevano raccontare storie di eventi accaduti in qualsiasi momento nel passato, quindi abbiamo dovuto supportare date sfocate. Dopo molto avanti e indietro, la soluzione a cui siamo arrivati ​​è molto simile al suggerimento di superM qui, in cui le date sono memorizzate come istanti min e max possibili che conterrebbero la data della storia. Quando si riporta la data, l'accuratezza (ovvero "questo record è preciso al mese / anno / giorno") può essere estratta dal delta tra le date min e max. Non è necessario memorizzare un terzo campo per la precisione.
Meetamit

4
+1 per min datee max datecampi. Penso che sia la soluzione più flessibile, precisa e facile da usare.
Supr

1
All'inizio ero antagonista a questa idea. Ma realizzando che è l'approccio più flessibile, voto per questo.
Anurag Kalia

È solo naturale. Stai descrivendo non tanto una data sfocata ma un periodo di tempo ..... che ha un inizio e una fine.
Pieter B,

20

Si tratta in realtà di una definizione dei requisiti più che di un problema tecnico - ciò su cui devi concentrarti è "come possiamo definire le date in passato" e la soluzione tecnica scorrerà.

Le volte in cui ho dovuto avvicinarmi a qualcosa del genere abbiamo in genere:

  • Definisci come mappare le cose - come suggerisce MichaelT , decidi che tutto ciò che viene definito come Mese / Giorno viene definito come mezzanotte il 1 ° di detto mese. Questo è in genere abbastanza buono per la maggior parte degli scopi - se la data esatta fosse così importante probabilmente ne avresti registrato 35 anni dopo, giusto?
  • Capire se è necessario tenere traccia di questo: IE, i record con date di creazione leggermente inventate richiedono una bandiera che lo dica? O è solo un problema di formazione degli utenti che la gente conosce e può agire di conseguenza.

A volte uno deve fare qualcosa come rendere le date sfocate - ad esempio, potrebbe essere necessario che una data risponda a una query per qualsiasi cosa nel maggio 1978. Questo è fattibile - basta creare i campi create_date 2, i vecchi record ottengono un 30 i giorni si diffondono secondo necessità, quelli nuovi ottengono 2 valori identici.


1
+1 - Stavo lavorando alla formulazione di una risposta con l'approccio del doppio appuntamento. La tua risposta è arrivata prima qui.

2
+1, è brutto e crea molte informazioni extra inutili per le nuove voci che non lo richiedono, ma d'altra parte mantiene le domande molto più semplici di quanto sarebbero altrimenti. Da tempo utilizziamo una soluzione simile per un problema correlato.
Izkata,

3
@Izkata: punto giusto, ma quanto elegante puoi ottenere quando devi creare qualcosa che dovrebbe essere un singolo punto nel tempo per un mese. Sicuramente più bello che dover calcolare l'inizio e la fine per le query al volo da qualche parte.
Wyatt Barnett,

1
+1 per essere in grado di indicare la granularità arbitraria senza un'esplosione di valori enumerici.
Dan Neely,

18

Il modo più semplice per indicare se la data è accurata è creare un campo di precisione INT (1) con valore NULL predefinito

Se la data è esatta, memorizza la data e l'ora in "data_creata" e lascia la precisione NULL

Se la data è accurata solo per il mese, memorizza la data-ora come 1 ° del mese con il valore di precisione 1

Se la data è accurata solo per la data del negozio dell'anno 1 gennaio con valore di precisione 2

Puoi usare numeri diversi per contenere valori diversi come il primo trimestre ecc


Le query diventano davvero pelose quando lo fai.
Blrfl

3
Ciò ha difficoltà con i dati che non si trovano su un limite di mese pulito come "Q2 1991" e "Winter 1978-1979".

1
OP vuole in qualche modo indicare che questa data è precisa solo per il mese.
David Strachan,

7
Stai abusando del significato di NULL qui. NULL significa "sconosciuto", quindi se la data è accurata, l'accuratezza non può essere NULL. Può essere '1'.
Konerak,

@Konerak Semanticamente sì. Ma poiché la maggior parte delle date sono accurate, solo i casi speciali devono essere identificati e usando NULL come impostazione predefinita.
David Strachan,

17

In passato ho archiviato le date con precisione come data di inizio e di fine. Il giorno maggio21,2012 sarebbe rappresentato come inizio = 12 maggio 21,2012 e fine = 12 maggio 22,2012. L'anno 2012 sarebbe rappresentato come inizio = 12 gennaio, 1.2012 fine = 12 gennaio, 1 gennaio 2013.

Non sono sicuro che consiglierei questo approccio. Quando si visualizzano le informazioni all'utente, è necessario rilevare correttamente che un intervallo di date copre esattamente un giorno per mostrare "25 maggio" invece di due endpoint troppo specifici (il che significa che si occupa dell'ora legale e così via).

Tuttavia, quando non stai cercando di tradurre in umano, la programmazione con gli endpoint è molto più semplice rispetto alla precisione center +. Non finisci con molti casi. È molto carino.


In realtà, non deve essere così complicato determinare come presentare un intervallo se l'intervallo è sempre memorizzato come UTC. Come timestamp UTC, ogni giorno, settimana, mese, anno - anche stagioni e trimestri - avranno due numeri costanti, globali, distinti e facilmente determinabili che rappresentano l'inizio e la fine del periodo. La logica diventa semplicemente alcune istruzioni if ​​per vedere se le due date sono all'inizio e alla fine di un certo tipo di periodo. Non sono necessarie complicazioni matematiche o di fuso orario :)
Supr

@Supr Determinare se un determinato secondo si trova al confine di un determinato periodo umano è, di per sé, un problema difficile. Soprattutto a lungo termine, con la rotazione della Terra che rallenta e interminabili piccoli cambiamenti nella definizione umana di ora locale.
Craig Gidney,

14

Perché non memorizzare due date.

Created_After e Created_Before. La semantica effettiva viene "creata sopra o dopo" e "creata sopra o prima"

Quindi, se conosci la data esatta, quindi Created_After e Created_Before saranno la stessa data.

Se sai che è stata la prima settimana di maggio 2000, Created_After = '2000-05-01' e Created_Before = '2000-05-07'.

Se conosci solo Maggio 1999, i valori saranno "1999-05-01" e "1999-05-30".

Se è "Summer of '42", i valori sarebbero "1942-06-01" e "1942-08-31".

Questo schema è semplice da interrogare con SQL normale e abbastanza facile da seguire per un utente non tecnico.

Ad esempio, per trovare tutti i documenti che potrebbero essere stati creati nel maggio 2001:

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

Al contrario, per trovare tutti i documenti che sono stati definitivamente creati nel maggio 2001:

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

1
Penso che questa sia la soluzione più elegante.
Pieter B,

Questo è lo stesso delle risposte di superM e Strilanc. +1 però per spiegare più chiaramente e mostrare quanto sarebbe semplice interrogare.
Supr

9

Il formato dell'ora della data ISO 8601 viene fornito con la definizione della durata, ad es

2012-01-01P1M (leggi: 2012, 1 gennaio, periodo: 1 mese) è quello che dovrebbe essere "a gennaio 2012".

Vorrei usare questo per memorizzare i dati. A tale scopo potrebbe essere necessario un campo di database di tipo String. È un argomento diverso su come condurre una ricerca ragionevole al riguardo.


+1 per l'idea ma -1 per non utilizzare un campo data per il motivo di come cercare e / o trovare
user151019

Dipende dal database. Tuttavia, questo può essere base per l'espansione, ma la domanda è: il documento nel set di risultati è se cerchi, in questo caso, tutti i documenti più recenti del 12 gennaio, o no? Non è banale. Qui, la domanda era come memorizzare le date sfocate.
Matthias Ronge,

3

In genere, li conservo ancora poiché le date per le attività di query generale sono ancora possibili anche se leggermente meno accurate.

Se è importante conoscere l'accuratezza che in passato ho memorizzato una "finestra" di accuratezza come +/- decimale o come ricerca (giorno, mese, anno, ecc.). In altri casi, invece della finestra, memorizzo semplicemente il valore della data originale come stringa e converto ciò che posso in un datetime, possibilmente 1978-05-01 00:00:00 e "Maggio 1978" per il tuo esempio.


3

Se lo dividi in più colonne, perdi la possibilità di interrogare.

Dice chi? Ecco cosa fai:

  1. Dispone di 3 colonne, giorno, mese, anno, ognuna di tipo int e una quarta colonna tipo TheDate of DateTime.
  2. Avere un trigger che utilizza le 3 colonne Giorno, Mese, Anno per compilare TheDate se TheDate viene lasciato nullo ma uno o più campi Day, Month, Year hanno un valore.
  3. Avere un trigger che popola i campi Giorno, Mese, Anno quando viene fornito TheDate ma questi campi non lo sono.

Quindi, se faccio un inserto come: insert into thistable (Day, Month, Year) values (-1, 2, 2012);allora TheDate diventerà il 2/1/2013 ma saprò che è davvero una data indeterminata nel 2/2012 a causa del -1 nel campo Giorno.

Se insert into thistable (TheDate) values ('2/5/2012');poi il giorno sarà 5, il mese sarà 2 e l'anno sarà il 2012 e poiché nessuno di essi è -1, saprò che questa è la data esatta.

Non perdo la possibilità di eseguire una query perché il trigger di inserimento / aggiornamento assicura che i miei 3 campi (giorno, mese, anno) producano sempre un valore DateTime in TheDate che può essere interrogato.


3

Un'altra opzione sarebbe quella di memorizzare le date come numeri interi del modulo YYYYMMDD.

  • Sai solo che l'anno è il 1951: Store as 19510000
  • Sai che il mese e l'anno sono marzo 1951: Store as 19510300
  • Sai che la data completa è il 14 marzo 1951: Store as 19510314
  • Una data completamente sconosciuta: conservare come 0

Benefici

Puoi memorizzare la tua data fuzzy in un campo invece di due campi data o una data e una precisione come suggeriscono molte altre risposte.

Le query sono ancora facili:

  • tutti i record per l'anno 1951 - SELECT * FROM table WHERE thedate>=19510000 and thedate<19520000
  • tutti i record per marzo 1951 - SELECT * FROM table where thedate>=19510300 and thedate<19510400
  • tutti i record per il 14 marzo 1951 - SELECT * FROM table where thedate=19510314

APPUNTI

  • La tua interfaccia grafica avrebbe bisogno di una GetDateString(int fuzzyDate)che è abbastanza facile da implementare.
  • L'ordinamento è semplice con il formato int. Dovresti sapere che prima verranno le date sconosciute. È possibile invertire ciò utilizzando 99"imbottitura" anziché 00per il mese o il giorno.

Come rappresenti la data sfocata dell '"inverno del 1941-1942"? Potrebbe essere il dicembre 1941 o il gennaio 1942.

1
La tua domanda è correlata a un caso di soluzione generale. La domanda originale non elenca questo come un problema. Sulla base della domanda pubblicata, a volte è nota la data completa, a volte solo l'anno e il mese, a volte solo l'anno. Nessun problema relativo a un intervallo di date fuzzy è menzionato come requisito. Concordo sul fatto che sono necessarie due date se fosse necessario risolvere questo problema (sebbene, la memorizzazione dell'intervallo come due "date sfocate" potrebbe fornire maggiore flessibilità rispetto alla memorizzazione di due date "difficili").
Rick,

1

ISO 8601 specifica anche una sintassi per "date fuzzy". Il 12 febbraio 2012 alle 15:00 sarebbe "2012-02-12T15" e febbraio 2012 potrebbe essere semplicemente "2012-02". Questo si estende bene usando l'ordinamento lessicografico 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

0

Ecco la mia opinione su questo:

Passa dalla data fuzzy all'oggetto datetime (che si adatta a un database)

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

E poi una funzione che prende l'oggetto datetime e lo sposta in una data sfocata.

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()

E poi un test unitario. Ho perso qualche caso?

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'

C'è un caso angolare in cui un evento che si è verificato precisamente 2001-01-01T00:00:00.333333ma il sistema interpreterà come "2001", ma sembra molto improbabile.


0

Lavoro per una casa editrice che si occupa di molti vecchi libri in cui spesso non siamo in grado di ottenere le date esatte per le cose. Di solito abbiamo due campi per una data data, la data e un booleano circa :

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

Usiamo il campo data per indicare la data di un evento o una data "abbastanza vicina" nel caso in cui non conosciamo la data vera. Nel caso in cui non conosciamo la data vera, contrassegniamo il dateCircacampo come Ye diamo una data abbastanza vicina, che è contrassegnata come "1", come

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

0

Panoramica

Esistono molte rappresentazioni possibili, e quindi schemi di database, per la memorizzazione di date-time fuzzy (o anche solo date fuzzy):

  1. Data-ora e codice che indicano la sua precisione o accuratezza
  2. Data-ora e intervallo in cui esistono diverse possibilità per rappresentare un intervallo:
    1. Rappresenta tutti gli intervalli come quantità intera (o altra quantità numerica) di alcune unità fisse, ad esempio giorni, minuti, nanosecondi.
    2. Rappresenta un intervallo sia come quantità intera (o altra quantità numerica) sia come codice che indica le sue unità.
  3. Data e ora di inizio e fine
  4. Corda
  5. Distribuzione di probabilità:
    1. Quantità decimali o in virgola mobile per i parametri che specificano una distribuzione specifica in una particolare famiglia, ad esempio media e deviazione standard di una distribuzione normale.
    2. Funzione di distribuzione della probabilità, ad es. Come codice (di ricerca) (potenzialmente con parametri di valori specifici) o come espressione in un linguaggio, formato o rappresentazione sufficientemente espressivi.

[1], [2] e [3] sono tutti (implicitamente) intervalli uniformi, ovvero un insieme di (ugualmente) possibili punti nel tempo.

[4] è il più espressivo, vale a dire quando si consente qualsiasi frase o frase scritta (o almeno arbitrariamente lunga) scritta. Ma è anche il più difficile con cui lavorare. Nel limite, l'intelligenza artificiale a livello umano sarebbe richiesta per gestire valori arbitrari. In pratica, l'intervallo di valori possibili dovrebbe essere severamente limitato e probabilmente i valori "strutturati" alternativi sarebbero probabilmente preferiti per molte operazioni, ad esempio ordinamento, ricerca.

[5] è probabilmente la rappresentazione compatta più generale che è (in qualche modo) pratica.

Intervalli uniformi

Gli intervalli uniformi sono il modo più semplice e compatto per rappresentare un insieme di (possibili) valori data-ora.

Per [1], le parti del valore data-ora vengono ignorate, vale a dire le parti corrispondenti alle unità più fini della precisione o accuratezza indicata; altrimenti questo equivale a [2] e il codice di precisione / accuratezza equivale a un intervallo con le stesse unità (e una quantità implicita di 1).

[2] e [3] sono espressamente equivalenti. [1] è strettamente meno espressivo di uno dei due in quanto vi sono intervalli effettivi che non possono essere rappresentati da [1], ad es. una data-ora sfocata equivalente a un intervallo di 12 ore che attraversa un limite di data.

[1] è più facile da inserire per gli utenti rispetto a qualsiasi altra rappresentazione e in genere dovrebbe richiedere (almeno leggermente) meno digitazione. Se è possibile inserire date-ora in varie rappresentazioni di testo, ad esempio "2013", "2014-3", "2015-5-2", "30/07/2016 11p", "2016-07-31 18:15" , la precisione o accuratezza potrebbe anche essere dedotta automaticamente dall'input.

L'accuratezza o la precisione di [1] è anche la più facile da convertire in un modulo da trasmettere agli utenti, ad esempio "2015-5 con accuratezza mensile" in "Maggio 2015", rispetto a "13 maggio 2015 2p, più o meno 13,5 giorni" (nota che quest'ultimo non può essere rappresentato comunque da [1]).

stringhe

In pratica, i valori di stringa dovranno essere convertiti in altre rappresentazioni per l'interrogazione, l'ordinamento o il confronto di più valori. Quindi, mentre qualsiasi linguaggio naturale (umano) scritto è strettamente più espressivo di [1], [2], [3] o [5], non abbiamo ancora i mezzi per gestire molto oltre le rappresentazioni o i formati di testo standard. Detto questo, questa è probabilmente la rappresentazione meno utile da sola .

Un vantaggio di questa rappresentazione è che i valori dovrebbero, in pratica, essere presentati agli utenti così come sono e non richiedere che la trasformazione sia facilmente comprensibile.

Distribuzioni di probabilità

Le distribuzioni di probabilità generalizzano le rappresentazioni di intervallo uniforme [1], [2], [3] e (probabilmente) equivalgono alla rappresentazione (generale) di stringhe [4].

Un vantaggio delle distribuzioni di probabilità sulle stringhe è che il primo non è ambiguo.

[5-1] sarebbe appropriato per valori che (principalmente) si conformano a una distribuzione esistente, ad esempio un valore di data e ora emesso da un dispositivo per il quale le misurazioni sono note (o ritenute) conformi a una distribuzione specifica.

[5-2] è probabilmente il modo migliore (in qualche modo) pratico per rappresentare in modo compatto valori arbitrari di "datetime fuzzy". Naturalmente la calcolabilità delle specifiche distribuzioni di probabilità ha usato la materia e ci sono sicuramente problemi interessanti (e forse impossibili) da risolvere quando si interrogano, si ordinano o si confrontano valori diversi, ma molto di questo è probabilmente già noto o risolto da qualche parte nell'esistente letteratura matematica e statistica, quindi questo rappresenta sicuramente una rappresentazione estremamente generale e non ambigua.



-2

Nel tuo caso hai bisogno solo di anno, mese e giorno. Sono richiesti anno e mese, il giorno è facoltativo. Userei qualcosa del genere:

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

Inoltre, puoi comunque utilizzare gli indici in modo molto efficace. Il (minuscolo = meno, le code diventano un po ' più "complicate" (più a lungo).


1
Ma questo significa che se la confusione divora anche la parte del mese, questo approccio fallisce.
Anurag Kalia,

1
@AnuragKalia - quindi rendere il campo del mese nulla. Nessun motivo per cui non è stato possibile riconfigurarlo in un secondo momento.
JeffO,

Quello era solo un esempio. La soluzione deve essere abbastanza generale da soddisfare i problemi futuri. Se l'intervallo specificato è compreso tra il 15 marzo 2013 e il 22 marzo 2013, questo approccio non funziona. La risposta min-max sopra è la più generale finora.
Anurag Kalia

1
Hai trovato questo requisito nei post di OP o è solo la tua fantasia?
Danubian Sailor,

Rendere il mese nullable consente di specificare un giorno ma nessun mese. Non ha nemmeno senso. Quando era 1978-??-31?
MSalters,

-2

Vorrei semplicemente memorizzare l'ora esatta per le date normali e rendere generica la parte dell'ora della data fuzzy come 00:00:00. Vorrei quindi rendere tutte le date sfocate il 1 ° del mese.

Quando fai una query, tu

  1. controlla gli intervalli di date in cui l'ora è uguale a 00:00:00 (fuzzy)
  2. verifica gli intervalli di date in cui l'ora NON è uguale a 00:00:00 (reale)
  3. controlla gli intervalli di date ma ignora la parte temporale (combinata)

Esistono soluzioni migliori di questa, ma io odio personalmente i metadati (dati sui miei dati). Ha solo l'abitudine di sfuggire di mano dopo un po '.


2
come si farebbe con la data reale che ha l'ora 00:00:00?
moscerino del

Mentre è teoricamente possibile aggiungere una data reale con quel tempo, non accadrà. Ho visto tabelle con milioni di righe e nessuna di esse aveva un valore datetime in cui l'ora era 00:00:00. Il pragmatismo batte la convenzione.
Capitano Kenpachi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.