Eu provavelmente escolheria um daterange coluna.
Isso lhe dá a flexibilidade de ter blocos de tamanhos diferentes e permite definir um restrição de exclusão para evitar intervalos sobrepostos.
Encontrar a linha de uma determinada semana ainda é bastante simples usando o operador "contém"
@>
, por exemplo. where the_column @> to_date('2019-24', 'iyyy-iw')
encontra as linhas que contêm o número da semana 24 em 2019. A expressão
to_date('2019-24', 'iyyy-iw')
retorna o primeiro dia (segunda-feira) da semana especificada. Encontrar todas as linhas que estão entre duas semanas também pode ser feito, no entanto, a construção do intervalo de datas correspondente parece um pouco feia. Você pode construir um intervalo inclusivo com o primeiro e o último dia:
daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-24', 'iyyy-iw') + 6, '[]')
Ou você pode criar um intervalo com um intervalo superior exclusivo com o primeiro dia da próxima semana:
daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-25', 'iyyy-iw'), '[)')
Embora os intervalos possam ser indexados com bastante eficiência e , os índices GIST necessários são um pouco mais caros de manter do que um índice B-Tree em duas colunas inteiras.
Outra desvantagem de usar intervalos (se você realmente não precisa de flexibilidade) é que eles ocupam mais espaço do que duas colunas inteiras (14 bytes em vez de 8, ou até 4 com dois smallint). Portanto, se o tamanho da tabela for uma preocupação, sua solução atual com as colunas ano/semana será mais eficiente.
Se sua entrada for uma data de início e término para começar (em vez de um "número da semana"), eu definitivamente usaria um
daterange
coluna. Se essa data de início e término abranger mais de uma semana, você armazena apenas uma linha, em vez de várias linhas.