Probablemente elegiría un daterange columna.
Eso le brinda la flexibilidad de tener fragmentos de diferentes tamaños y le permite definir un restricción de exclusión para evitar la superposición de rangos.
Encontrar la fila para una semana dada sigue siendo bastante simple usando el operador "contiene" @>
, p.ej. where the_column @> to_date('2019-24', 'iyyy-iw')
encuentra la(s) fila(s) que contienen la semana número 24 en 2019.
La expresión to_date('2019-24', 'iyyy-iw')
devuelve el primer día (lunes) de la semana especificada.
También se pueden encontrar todas las filas que están entre dos semanas, sin embargo, la construcción del rango de fechas correspondiente se ve un poco fea. Puede construir un rango inclusivo con el primer y último día:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-24', 'iyyy-iw') + 6, '[]')
O puede crear un rango con un rango superior exclusivo con el primer día de la próxima semana:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-25', 'iyyy-iw'), '[)')
Si bien los rangos se pueden indexar de manera bastante eficiente, los índices GIST requeridos son un poco más costosos de mantener que un índice B-Tree en dos columnas enteras.
Otra desventaja de usar rangos (si realmente no necesita la flexibilidad) es que ocupan más espacio que dos columnas de enteros (14 bytes en lugar de 8, o incluso 4 con dos smallint). Entonces, si el tamaño de la tabla es motivo de preocupación, entonces su solución actual con las columnas año/semana es más eficiente.
Si su entrada es una fecha de inicio y finalización para comenzar (en lugar de un "número de semana"), definitivamente optaría por un daterange
columna. Si esa fecha de inicio y finalización cubre más de una semana, entonces almacena solo una fila, en lugar de varias filas.