Due campi di database per data e ora - dovrebbero essere uniti?

7

Nella seguente domanda, i nomi dei campi e delle tabelle sono stati modificati per proteggere le loro identità.

Se ho due colonne del database:

MONKEY_DATE DATETIME NULL (with data e.g. 2012-05-14 00:00:00.000)
MONKEY_TIME DATETIME NULL (with data e.g. 1753-01-01 16:30:53.025)

Il componente data del campo orario è per lo più impostato al 1 ° gennaio 1753 ... ma alcuni dati sono il 1 ° gennaio 1899 e alcuni hanno il 1 ° gennaio 1900.

Trovo che mantenere il codice per interrogare e riportare su queste colonne possa causare a me (e al nostro team) un mal di testa che potrebbe facilmente essere risolto unendo le due colonne. Tuttavia, l'esperienza (e Terry Goodkind ) mi ha insegnato che niente è mai facile. Vedi sotto alcuni esempi del perché questo è un mal di testa.

Il mio approccio

Penso che il seguente approccio avrà l'effetto desiderato di unire le due colonne:

  1. Utilizzare SQL per aggiornare i dati, impostando il valore per il campo data e il valore per il campo orario entrambi sullo stesso valore, che è un mix del componente data dal campo data e il componente orario dal campo ora
  2. Scrivi qualsiasi nuovo codice solo utilizzando il campo MONKEY_DATE
  3. Eventualmente eliminare gradualmente il campo MONKEY_TIME e qualsiasi componente SQL di data / ora (vedi esempi)
  4. Elimina MONKEY_TIME

Questo significa che non dobbiamo immediatamente apportare modifiche retrospettive all'intero sistema ... tutto il codice esistente continuerà a funzionare ... e possiamo iniziare a fare le cose nel modo giusto.

SQL per # 1 potrebbe essere (Oracle):

UPDATE MONKEY SET 
    MONKEY_DATE = TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY ') || 
                      TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 
                      'MM/DD/YYYY HH24:MI:SS')
    MONKEY_TIME = TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY ') || 
                      TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 
                      'MM/DD/YYYY HH24:MI:SS')

La domanda

Le mie domande sono:

  • Questi campi dovrebbero essere uniti?
  • Il mio approccio è ragionevole per unire queste due colonne?
  • Pensi che sarebbe meglio saltare i passaggi due e tre?
  • Hai altri commenti o suggerimenti (costruttivi)?

Esempi

Ad esempio, per selezionare tutte le date e le ore della mia scimmia e ordinarle per data e ora, ho bisogno di fare qualcosa del genere (SQL Server):

SELECT 
      CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_DATE, 101), 101) AS MONKEY_DATE
    , CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_TIME, 108), 108) AS MONKEY_TIME 
FROM MONKEY 
ORDER BY
      CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_DATE, 101), 101) DESC
    , CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_TIME, 108), 108) DESC

o questo (Oracle - leggermente più esplicito):

SELECT
      TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY'), 'MM/DD/YYYY') AS MONKEY_DATE
    , TO_DATE(TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 'HH24:MI:SS') AS MONKEY_TIME
FROM MONKEY
ORDER BY
      TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY'), 'MM/DD/YYYY') DESC
    , TO_DATE(TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 'HH24:MI:SS') DESC

Spesso mi trovo anche a selezionare una colonna data / ora unificata (Oracle):

SELECT 
    TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY ') || 
            TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 
        'MM/DD/YYYY HH24:MI:SS') AS MONKEY_DATE_TIME 
FROM MONKEY

Perché, quasi sempre, vogliamo sapere la data e l'ora della scimmia.

Il precedente SQL potrebbe essere facilmente modificato in:

SELECT MONKEY_DATE_TIME FROM MONKEY ORDER BY MONKEY_DATE_TIME

... Se solo avessimo colonne unite.

Sfondo

Ho ereditato un vecchio sistema ASP che memorizza le date e le ore in colonne separate nel database. Mi è stato detto che questo è probabilmente dovuto al fatto che l'applicazione è stata avviata in una versione precedente di Access, in cui non era possibile memorizzare sia la data che l'ora nella stessa colonna. I perché e i come non fanno realmente parte di questa domanda, ma alcune persone amano sapere.

P.S.

L'ho davvero pubblicato in SO.SE, quindi mi scuso se ho trovato il sito sbagliato.

    
posta oliver-clare 14.05.2012 - 17:50
fonte

5 risposte

14

Un punto secondario: QUANDO unisci le due colonne, potresti voler eseguire l'unione in una nuova colonna "MONKEY_DATE_2" invece di sovrascrivere quella esistente. Ciò lascia invariate le tue colonne attuali e puoi trovare tutto il codice che non è stato aggiornato per funzionare con la nuova struttura con grep.

    
risposta data 14.05.2012 - 18:01
fonte
6

Sì, penso che dovrebbero essere uniti. Normalmente non mi preoccuperei di separare i campi data e ora a meno che non ci siano buone ragioni per farlo. I sistemi legacy potrebbero essere stati una buona ragione, ma se i dati sono stati migrati a un sistema in grado di gestire date e orari combinati, l'unione è una buona idea.

Per quanto riguarda il tuo approccio, sembra ragionevole. Potresti anche eseguire un piccolo progetto di refactoring per correggere tutto il codice allo stesso tempo per assicurarti che tutte le tue query siano corrette insieme per eliminare "Eventualmente eliminare il campo MONKEY_TIME", anche se potrebbe richiedere del tempo e probabilmente richiederà test di regressione significativi. Quale non dovrebbe essere un problema se pianifichi in anticipo per esso.

Indagare anche se esistono sistemi a valle (come servizi web o sistemi di reporting esterni) che sono costruiti da basi di codice differenti ma dipendono ancora da valori separati di data e ora. Se tali sistemi esistono, dovranno anche far parte di questo piano.

    
risposta data 14.05.2012 - 17:56
fonte
2

Se la data e l'ora vengono sempre utilizzate insieme, quindi con tutti i mezzi, unisci le colonne e ottieni i benefici di un minor numero di mal di testa.

Cose a cui prestare attenzione:

  • Uso della colonna del tempo per il calcolo del tempo relativo in giorni (ad es. "selezione delle scimmie che sono andate banane in qualsiasi giorno alla volta entro un'ora da quando questa scimmia ha fatto banane").
  • Aritmetica nella colonna della data che non tratta i giorni frazionari in modo sano.
  • Uso della colonna della data come meccanismo di raggruppamento.

Se hai query esistenti particolarmente appiccicose, crea una vista aggiornabile che emuli il vecchio comportamento fino a quando non riesci a risolverli.

    
risposta data 14.05.2012 - 20:31
fonte
1

Ho avuto un problema simile a un precedente periodo di lavoro. Dividiamo la data e l'ora in due colonne DB. Questo ci ha causato un sacco di mal di testa. > _ < Detto questo, raccomando vivamente di passare a una singola colonna datetime nel DB. Ciò manterrà un sacco di bug da strisciante.

Per quanto riguarda la tua strategia, sembra ragionevole, ma assicurati di coinvolgere tutta la squadra in questa decisione e nel refactoring. Devi attivamente scoraggiare chiunque dall'usare il vecchio schema dei dati.

Se non sono richieste molte modifiche al codice (e hai un po 'di tempo in più!), puoi considerare di effettuare il cambiamento tutto in una volta e di non avere un passaggio "intermedio" in cui supporti entrambi gli schemi di dati. Tuttavia, questo è generalmente improbabile, quindi probabilmente avrai bisogno di una sorta di piano di migrazione come quello che hai citato nel passaggio 2/3

    
risposta data 14.05.2012 - 17:55
fonte
0

Se stai modificando gradualmente questo cambiamento nel tempo (invece di preparare tutte le modifiche e quindi di installare tutto in una volta), devi fare attenzione a non leggere i valori nel modo in cui erano scritti nel vecchio modo. Quindi la transizione dovrebbe andare:

  1. Tutte le nuove scritture scrivono sia nel nuovo modo che nel vecchio modo (l'utilizzo di una nuova colonna per il nuovo modo sarebbe d'aiuto) e legge la vecchia maniera. Il codice esistente viene modificato per scrivere sia alla nuova maniera che alla vecchia maniera.

  2. Una volta che tutto il codice sta scrivendo in entrambi i modi, converti i dati esistenti in modo che siano disponibili in entrambi i modi.

  3. Tutto il nuovo codice legge il nuovo modo (e scrive ancora in entrambi i modi). Il codice esistente viene modificato per leggere il nuovo modo.

  4. Una volta che tutto il codice sta leggendo il nuovo modo, il nuovo codice può scrivere solo il nuovo modo e il codice esistente può essere modificato solo per scrivere il nuovo modo.

  5. Una volta che tutto il codice legge e scrive il nuovo modo e nessun codice fa riferimento alle vecchie colonne, è possibile rimuoverle.

Il nuovo modo (una colonna con data e ora) sembra ovviamente migliore per me, devi decidere se è sufficiente un miglioramento per passare attraverso il processo di conversione.

    
risposta data 14.05.2012 - 19:47
fonte

Leggi altre domande sui tag