Jag skulle förmodligen välja ett datumintervall kolumn.
Det ger dig flexibiliteten att ha olika stora bitar och låter dig definiera en uteslutningsbegränsning för att förhindra överlappande intervall.
Att hitta raden för en viss vecka är fortfarande ganska enkelt med operatorn "innehåller" @>
, t.ex. where the_column @> to_date('2019-24', 'iyyy-iw')
hittar raden/raderna som innehåller vecka nummer 24 under 2019.
Uttrycket to_date('2019-24', 'iyyy-iw')
returnerar den första dagen (måndag) i den angivna veckan.
Att hitta alla rader som ligger mellan två veckor kan också göras, men konstruktionen av motsvarande datumintervall ser lite ful ut. Du kan antingen skapa ett inkluderande intervall med den första och sista dagen:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-24', 'iyyy-iw') + 6, '[]')
Eller så kan du skapa ett intervall med ett exklusivt övre intervall med nästa veckas första dag:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-25', 'iyyy-iw'), '[)')
Även om intervall kan indexeras ganska effektivt och , är de nödvändiga GIST-indexen lite dyrare att underhålla än ett B-Tree-index på två heltalskolumner.
En annan nackdel med att använda intervall (om du egentligen inte behöver flexibiliteten) är att de tar upp mer utrymme än två heltalskolumner (14 byte istället för 8, eller till och med 4 med två smallint). Så om storleken på tabellen är av någon anledning, är din nuvarande lösning med år/vecka kolumner mer effektiv.
Om din inmatning är ett start- och slutdatum till att börja med (snarare än ett "veckonummer"), så skulle jag definitivt välja ett daterange
kolumn. Om start- och slutdatumet omfattar mer än en vecka, lagrar du bara en rad istället för flera rader.