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.