Come memorizzare sequenze temporali sequenziali in un database?

2

Come possono consecutivi periodi di tempo (definiti da una data di inizio e di fine) essere memorizzati in un database? Ad esempio:

  • dal 2018-01-01 00: 00: 00 + 01: 00 fino al 2018-06-01 00: 00: 00 + 02: 00
  • dal 2018-06-01 00: 00: 00 + 02: 00 fino al 2018-10-01 00: 00: 00 + 02: 00
  • dal 2018-10-01 00: 00: 00 + 02: 00 in poi (che significa 'indefinitamente')

Il fattore importante è che la data di fine di un singolo intervallo deve sempre corrispondere alla data di inizio di un altro.

Preoccupazioni principali:

  • Memorizzando lo stesso valore (data di fine di uno, data di inizio del prossimo) due volte risulta subottimale. I vincoli sarebbero una necessità per evitare le irregolarità.
  • Non memorizzare la data di fine e utilizzare la data di inizio di un altro record / riga rende difficile ogni singola riga su cui ragionare. La ricerca diventa più difficile.

Entrambe le preoccupazioni mi chiedono se esiste un approccio migliore?

    
posta smhg 25.09.2018 - 11:55
fonte

2 risposte

9

Not storing the end date and using the start date of a different record/row make each individual row hard to reason about. Querying gets harder.

SQL Server 2012 ha introdotto LEAD e LAG per aiutare con questi tipi di query. Spiegazione completa qui .

Un breve esempio per il tuo caso:

SELECT 
    StartDate,        
    LEAD(StartDate) OVER (ORDER BY StartDate) as EndDate
FROM
    MyTable

Ciò consente di memorizzare solo la data di inizio nella tabella del database, ma poi crea una vista che restituisce una tabella che contiene sia la data di inizio (memorizzata) che la data di fine (calcolata).

Questo ti dà il meglio di entrambi i mondi. Internamente, garantisci l'integrità dei dati. Esternamente, hai una vista più facile da elaborare / interrogare ulteriormente.

Nel complesso, la tua valutazione è corretta. Memorizzare la data di fine / inizio due volte è più semplice (a costo di integrità dei dati), mentre rimuovere i valori duplicati ti dà una migliore integrità dei dati (ma richiede più sforzi per implementare .

Questo tipo di problema è spesso un tipo di affare "scegli il tuo veleno". Ad esempio, prendere in considerazione l'esempio di memorizzare le dimensioni di cartella / file in un sistema di directory. Ciò rende il problema un po 'più evidente, a causa della natura ricorsiva delle strutture di directory.

  • Memorizzi una dimensione per ogni cartella separatamente? Quindi devi solo interrogare la cartella per trovare la sua dimensione, ma è possibile che tu memorizzi i dati in modo che la dimensione della directory principale non sia uguale alla dimensione totale del suo contenuto (= query veloce, ma aperta all'incoerenza dei dati)
  • Calcoli le dimensioni di una directory di primo livello in base al suo contenuto? Quindi hai la certezza di ottenere la risposta giusta, ma devi calcolare ricorsivamente la dimensione del contenuto della cartella ogni volta che vuoi conoscere la dimensione di una cartella (= coerenza dei dati garantita, ma query lenta)

Ma questa è una scelta che dovrai fare. Quali sono le tue priorità? Velocità di sviluppo? O qualità / coerenza? Non esiste una risposta vera.

    
risposta data 25.09.2018 - 12:36
fonte
0

Una possibilità è di normalizzare le date in una tabella separata. Creare una tabella con una sequenza (numero autonumber o qualsiasi cosa usi il database) come chiave primaria e data / ora come seconda colonna. Quindi la relazione tra la tabella originale e la tabella data / ora implicherà semplicemente la memorizzazione della chiave primaria data / ora in entrambi i campi. Ad esempio, se il tuo primo intervallo è dal 2001-01-01T12: 30: 00z al 2004-01-02T12: 30: 01z e il tuo secondo è dal 2004-01-02T12: 30: 01z al 2006-02-02T11: 30 : 01z, memorizzi le tre date nella tabella date:

ID Date 
 1  2001-01-01T12:30:00z 
 2  2004-01-02T12:30:01z
 3  2006-02-02T11:30:01z

Quindi nella tabella degli eventi originale fai riferimento alla tabella delle date

Name    Start_ID End_ID
 BEFORE  1        2   
 DURING  2        3
 AFTER   3        null 

L'AFTER è un esempio se vuoi lasciare un intervallo di date aperto al presente e magari modificarlo più tardi quando termina il periodo di DOPO.

    
risposta data 25.09.2018 - 15:47
fonte

Leggi altre domande sui tag