PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Problema de alocação de horas semanais em Rails e Postgresql


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.