web-dev-qa-db-ja.com

オープン状態が日付範囲を表し、クローズ状態が範囲間のギャップを表すAPIからのイベントの日付範囲を作成する方法は?

PostgreSQLに、オープンまたはクローズの状態と、状態が変化した日時のいくつかの任意のイベントの日時範囲を保存したいと思います。

APIからのイベントには、1つのイベントについて次のデータが含まれます。

Request 1:
{
  id: 1,
  state: 'open',
  date: '2020-02-17T10:00:00Z'
}

Request 2:
{
  id: 1,
  state: 'close',
  date: '2020-02-17T10:10:00Z'
}

Request 3:
{
  id: 1,
  state: 'open',
  date: '2020-02-17T11:00:00Z'
}

リクエストは任意の順序で発生する可能性があるため、将来の日付が過去の日付よりも前になる可能性があります。たとえば、APIは同じイベントのオープン状態を次々と送信できます。

このデータを次の形式でデータベースに保存するためにtstzrangeを使用することを考えていました。

CREATE TABLE events (
  id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  event_id int,
  validity tstzrange
);

オープン状態は有効性列にキャプチャされ、クローズ状態は有効性列間のギャップです。たとえば、1つのイベントに次の状態と日付/時刻(単純にするために時間のみを使用)がある場合、

state          date/time
close          20:30
open           18:00
close          16:00
open           15:00
open           20:00
close          19:30

有効性の行は次のようになります。

id          event_id           validity
1           1                  [15:00, 16:00)
2           1                  [18:00, 19:30)
3           1                  [20:00, 20:30)

Event 1は、15:00 - 16:00の間の状態open16:00 - 18:00の間の状態close18:00 - 19:30の間の状態openを持っています。オン。

これを視覚的に説明するには:

validity visualized

私の問題は、イベントが順番に来ていないため、これらの行を挿入/更新するために個々の有効性列を操作する方法がわかりません。

1
feketegy

アルゴリズムの観点から、この種のデータをPostgreSQLの日付範囲に挿入/更新する方法を理解したので、これも役立つかもしれません。

このデータは時系列であるため、最終的には完全なデータセットがわかっている場合、単一のイベントのオープン状態とクローズ状態が時間の経過によって重複することはありません。

アルゴリズムを十分に柔軟に保ちます。イベントの全範囲と開閉状態がわからない場合のために、考慮する必要があるいくつかのルールがあります。

イベントの日付と次の情報を含む有効性の列がある場合:

  1. イベントの状態がopenの場合:

1.1。包含妥当性に負の無限大がある場合=包含妥当性の下限をイベントの日付に更新します。

1.2。含まれている有効性の直前に別の有効性行がある場合、つまり含まれている有効性の下限が別の有効性の上限に等しい場合=含まれている有効性の下限がイベントの日付に更新されます。

1.3。上記のポイントがfalseの場合=含まれている有効性を2つの別々の行に分割します。

1.3.1。含まれている有効性の下限をイベントの日付に更新します。 1.3.2。下限が有効性の元の下限で、上限がイベントの日付である新しい行を挿入します。

  1. イベントの状態がcloseの場合(オープン状態のルールの逆):

2.1。包含妥当性に正の無限大がある場合=包含妥当性の上限をイベントの日付に更新します。

2.2。含まれている有効性の後に厳密に別の有効性行がある場合、つまり含まれている有効性の上限が別の有効性の下限と等しい場合=含まれている有効性の上限がイベントの日付に更新されます。

2.3。上記のポイントがfalseの場合=含まれている有効性を2つの別々の行に分割します。

2.3.1。含まれている有効性の上限をイベントの日付に更新します。

2.3.2。上限が有効性の元の上限で、下限がイベントの日付である新しい行を挿入します。

イベントの日付を含む有効範囲がない場合:

  1. イベントの状態がopenの場合、下限がイベントの日付に設定され、上限が正の無限大に設定された新しい有効性行を挿入します。

  2. イベントの状態がcloseの場合、上限がイベントの日付に設定され、下限が負の無限大に設定された新しい有効性行を挿入します。

これらのルールは、open状態が有効性列自体にキャプチャされ、close状態が有効性行間のギャップであるイベント状態の最良の図を提供します。

履歴データまたは現在のデータのいずれかから、ますます多くのデータが入ってくると、有効性の列は、時間の経過に伴うイベントの状態をより明確に示します。

0
feketegy