Domanda

Sto costruendo una base di dati di analisi (ho una solida conoscenza dei dati e gli obiettivi di business e le competenze di base solo a moderata database).

Mi sono imbattuto in alcuni riferimenti per la costruzione di magazzini simili che implementano il concetto di "tavoli di calendario. Questo ha senso ed è abbastanza presto fatto. La maggior parte degli esempi che vedo, però, sono le tabelle del calendario portata limite al 'giorno'. I miei dati dovranno essere analizzati fino a ora di livello. Possibilmente minuti.

La mia domanda: sarebbe un'implementazione di tavoli di calendario per / minuto livello di granularità ora essere di valore in termini di spazio-efficienza e di query / smistamento velocità? Se è così, si può consigliare una struttura di tabella e il metodo di popolazione / esempio?

Il mio tavolo dati primari conterrà oltre 20 milioni di righe di dati in qualsiasi momento e sottoinsiemi tipici per l'analisi sono nel range da 1 a 5 milioni. Quindi, come si può vedere, che è un sacco di campi data e ora.

È stato utile?

Soluzione

tavoli Calendario implementano un compromesso spazio / tempo. Utilizzando più spazio, alcuni tipi di query eseguite in meno tempo, perché possono usufruire di indici. Sono sicuro finché si sta attenti con il controllo () i vincoli, e finché si dispone di processi amministrativi di prendersi cura di tutti i vincoli che i DBMS non supporta.

Se la granularità è di un minuto, avrete bisogno di generare circa mezzo milione di righe per ogni anno. Una tabella di calendario minimo sarebbe simile a questa.

2011-01-01 00:00:00
2011-01-01 00:01:00
2011-01-01 00:02:00
2011-01-01 00:03:00
2011-01-01 00:04:00

Se stai facendo l'analisi "secchio", si potrebbe essere meglio con qualcosa di simile.

bucket_start         bucket_end
--
2011-01-01 00:00:00  2011-01-01 00:01:00
2011-01-01 00:01:00  2011-01-01 00:02:00
2011-01-01 00:02:00  2011-01-01 00:03:00
2011-01-01 00:03:00  2011-01-01 00:04:00
2011-01-01 00:04:00  2011-01-01 00:05:00

Dal momento che SQL di operatore BETWEEN include gli endpoint, di solito è necessario evitare di utilizzarlo. Questo perché include gli endpoint, ed è difficile esprimere bucket_end come "bucket_start più di un minuto, meno il più piccolo po 'di tempo questo server in grado di riconoscere". (Il pericolo è un valore che è maggiore di microsecondo bucket_end, ma ancora inferiore al valore successivo per bucket_start.)

Se dovessi costruire quel tavolo, probabilmente sarei fare in questo modo. (Anche se mi piacerebbe pensare di più sul fatto che avrei dovuto chiamarlo "calendario".)

create table calendar (
  bucket_start timestamp primary key,
  bucket_end timestamp unique,
  CHECK (bucket_end = bucket_start + interval '1' minute)
  -- You also want a "no gaps" constraint, but I don't think you 
  -- can do that in a CHECK constraint in PostgreSQL. You might
  -- be able to use a trigger that counts the rows, and compares
  -- that count to the number of minutes between min(bucket_start)
  -- and max(bucket_start). Worst case, you can always run a report
  -- that counts the rows and sends you an email.
);

Il vincolo UNIQUE crea un indice implicito in PostgreSQL.

Questa query inserire valore di un giorno di righe (24 ore * 60 minuti) alla volta.

insert into calendar
select coalesce(
                (select max(bucket_start) from calendar), 
                 cast('2011-01-01 00:00:00' as timestamp)
               ) 
             + cast((n || 'minute') as interval) as bucket_start, 
       coalesce(
                (select max(bucket_start) from calendar), 
                 cast('2011-01-01 00:00:00' as timestamp)
               ) 
             + cast((n + 1 || ' minute') as interval) as bucket_end
from generate_series(1, (24*60) ) n;

Si può avvolgere che in una funzione per generare un anno alla volta. Probabilmente sarei provare a commettere meno di mezzo milione di righe alla volta.

Non dovrebbe richiedere troppo tempo per generare 20 milioni di righe per i test, e altri 20 milioni di righe di minuti "calendario". lungo pranzo. Forse un pomeriggio al sole.

Altri suggerimenti

In PostgreSQL, è possibile generare tabelle di calendario di lunghezza arbitraria e granularità al volo:

SELECT  CAST('2011-01-01' AS DATE) + (n || ' hour')::INTERVAL
FROM    generate_series(0, 23) n

Questo non necessita ricorsione (come con gli altri sistemi) ed è un metodo preferito per generare gruppi di risultati volatili.

Nelle warehouse ho costruito usavo CALENDARIO e TIME_OF_DAY dimensioni separate. La prima dimensione ha un giorno granularità 1 giorno e la seconda -. 1 minuto granularità

In altri due casi sapevo in anticipo che nessuna segnalazione sarebbe richiesto al granularità più piccolo di 15 minuti. In tal caso, per semplicità che stavo usando una sola dimensione calendario con 96 registrazioni al giorno.

Stavo usando questo approccio nei magazzini Oracle finora, ma potrei essere coinvolto in un progetto di magazzino PostgreSQL questa estate.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top