PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wöchentliches Stundenzuweisungsproblem in Rails und Postgresql

Ich würde mich wahrscheinlich für einen daterange entscheiden Säule.

Das gibt Ihnen die Flexibilität, Chunks unterschiedlicher Größe zu haben, und ermöglicht Ihnen, einen Ausschlussbedingung um überlappende Bereiche zu vermeiden.

Das Auffinden der Zeile für eine bestimmte Woche ist immer noch recht einfach, indem Sie den "enthält"-Operator @> verwenden , z.B. where the_column @> to_date('2019-24', 'iyyy-iw') findet die Zeile(n) mit der Kalenderwoche 24 im Jahr 2019.

Der Ausdruck to_date('2019-24', 'iyyy-iw') gibt den ersten Tag (Montag) der angegebenen Woche zurück.

Es ist auch möglich, alle Zeilen zu finden, die zwischen zwei Wochen liegen, aber die Konstruktion des entsprechenden Datumsbereichs sieht etwas hässlich aus. Sie können entweder einen inklusiven Bereich mit dem ersten und letzten Tag erstellen:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-24', 'iyyy-iw') + 6, '[]')

Oder Sie können einen Bereich mit einem exklusiven oberen Bereich mit dem ersten Tag der nächsten Woche erstellen:daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-25', 'iyyy-iw'), '[)')

Während Bereiche recht effizient indiziert werden können, sind die erforderlichen GIST-Indizes etwas teurer in der Wartung als ein B-Tree-Index auf zwei Integer-Spalten.

Ein weiterer Nachteil der Verwendung von Bereichen (wenn Sie die Flexibilität nicht wirklich benötigen) ist, dass sie mehr Platz beanspruchen als zwei Integer-Spalten (14 Byte statt 8 oder sogar 4 mit zwei Smallint). Wenn also die Größe der Tabelle von Bedeutung ist, ist Ihre aktuelle Lösung mit den Jahres-/Wochenspalten effizienter.

Wenn Ihre Eingabe zunächst ein Start- und Enddatum ist (und nicht eine "Wochennummer"), dann würde ich mich definitiv für einen daterange entscheiden Säule. Wenn dieses Start- und Enddatum mehr als eine Woche umfassen, speichern Sie nur eine Zeile und nicht mehrere Zeilen.