Jeg ville nok gå efter en daterange kolonne.
Det giver dig fleksibiliteten til at have bidder af forskellig størrelse og giver dig mulighed for at definere en udelukkelsesbegrænsning for at forhindre overlappende intervaller.
At finde rækken for en given uge er stadig ret simpelt ved at bruge "indeholder" operatoren @>
, for eksempel. where the_column @> to_date('2019-24', 'iyyy-iw')
finder den eller de rækker, der indeholder uge nummer 24 i 2019.
Udtrykket to_date('2019-24', 'iyyy-iw')
returnerer den første dag (mandag) i den angivne uge.
Det kan også lade sig gøre at finde alle rækker, der er mellem to uger, men konstruktionen af det tilsvarende datointerval ser lidt grimt ud. Du kan enten bygge et inkluderende interval med den første og sidste dag:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-24', 'iyyy-iw') + 6, '[]')
Eller du kan oprette et område med et eksklusivt øvre område med den næste uges første dag:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-25', 'iyyy-iw'), '[)')
Mens intervaller kan indekseres ganske effektivt og , er de nødvendige GIST-indekser en smule dyrere at vedligeholde end et B-Tree-indeks på to heltalskolonner.
En anden ulempe ved at bruge områder (hvis du egentlig ikke har brug for fleksibiliteten) er, at de fylder mere end to heltalskolonner (14 byte i stedet for 8, eller endda 4 med to smallint). Så hvis størrelsen af tabellen giver anledning til bekymring, så er din nuværende løsning med år/uge kolonnerne mere effektiv.
Hvis dit input er en start- og slutdato til at begynde med (i stedet for et "ugenummer"), så ville jeg bestemt gå efter en daterange
kolonne. Hvis start- og slutdatoen dækker mere end én uge, gemmer du kun én række i stedet for flere rækker.