PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Problema di assegnazione delle ore settimanali in Rails e Postgresql

Probabilmente sceglierei un daterange colonna.

Ciò ti dà la flessibilità di avere blocchi di dimensioni diverse e ti consente di definire un vincolo di esclusione per evitare che gli intervalli si sovrappongano.

Trovare la riga per una determinata settimana è ancora abbastanza semplice utilizzando l'operatore "contiene" @> , per esempio. where the_column @> to_date('2019-24', 'iyyy-iw') trova le righe che contengono la settimana numero 24 nel 2019.

L'espressione to_date('2019-24', 'iyyy-iw') restituisce il primo giorno (lunedì) della settimana specificata.

È anche possibile trovare tutte le righe comprese tra due settimane, tuttavia la costruzione dell'intervallo di date corrispondente sembra un po' brutta. Puoi creare un intervallo inclusivo con il primo e l'ultimo giorno:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-24', 'iyyy-iw') + 6, '[]')

Oppure puoi creare un intervallo con un intervallo superiore esclusivo con il primo giorno della settimana successiva:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-25', 'iyyy-iw'), '[)')

Sebbene gli intervalli possano essere indicizzati in modo abbastanza efficiente e , gli indici GIST richiesti sono un po' più costosi da mantenere rispetto a un indice B-Tree su due colonne intere.

Un altro aspetto negativo dell'utilizzo degli intervalli (se non hai davvero bisogno della flessibilità) è che occupano più spazio di due colonne intere (14 byte invece di 8 o anche 4 con due smallint). Quindi, se la dimensione della tabella è preoccupante, la tua soluzione attuale con le colonne anno/settimana è più efficiente.

Se il tuo input è una data di inizio e di fine per cominciare (piuttosto che un "numero della settimana"), allora sceglierei sicuramente un daterange colonna. Se la data di inizio e di fine copre più di una settimana, memorizzi solo una riga, anziché più righe.