web-dev-qa-db-ja.com

Postgres jsonbカラムまたは標準正規化テーブル?

支払いシステムを備えたアプリを実装しています。アプリを通じて行われたトランザクションを記録する必要があります。また、いくつかのKPIをレンダリングするために、トランザクションに関する情報の一部を使用する必要があります。私のPostgresにはすでに実装があり、そのテーブルにはidおよびtransaction(jsonb)という2つの列があります。トランザクション列内には、次のようなオブジェクトがあります。

2018: {
   November: {
      list_of_transactions: [],
      totalAmountEarned: 0,
      numberOfTransactions: 0,
      avarageSpending: 0,
      numberOfCoins: 0,
      numberOfUsers: 0
   }  
}

ここで、トランザクションを作成するたびに、リクエストに付属するyearmonthが存在することを確認し、そうでない場合はそれらをオブジェクトに追加して、トランザクションをlist_of_transactionsにプッシュします、他のすべてのキーを適宜更新します。

これが問題に対処する良い方法なのか、それとも実際に本当に悪い方法なのか疑問に思いました。異なるテーブルを作成し、それらを「SQL形式」で正規化することはより良いソリューションですか?何か提案はありますか?

追加の考慮事項

副次的な質問:多くのトランザクションが発生するため、毎年新しいテーブルを作成することは良い考えですか?

関連するすべてのデータの構造はまったく同じであるため、複数のデータベースを作成して結合を行う必要があります。多くのトランザクションが発生するため、毎年新しいテーブルを作成することは良い考えですか?

7
user3353167

すべてのリレーショナルデータベースの経験則は正規化されています(通常、最大3NFまたは4NF)。リレーショナルの世界へのJSONの出現により、人々はJSONを使用してすべてを解決したくなることがよくあります。これは、アプリケーション内を移動するデータをデータベースにチャネリングする非常に簡単な方法を意味するためです。ただし、独自の場所がありますが、データの大部分または全体が正規化されている可能性が高いです。

基本的に、JSONが同じキー(同じデータ型の値を持つ)を共有していることがわかった場合は、それらのキーを適切な列に抽出する必要があります。構造全体が常に同じである場合は、すべてを抽出し、必要に応じてテーブルを作成します(JSONに配列がある場合、たとえば、それはそのキーのテーブルが必要な兆候である可能性があります)。世界-それらの間を結合します。

正規化によって解決されるすべての問題に加えて、これにはパフォーマンス上の利点もあります。まず、トランザクションごとに同じキーを何度も保存することはなく、おそらく多くのストレージ領域を節約します。次に、一般的なケースでは、列(またはそのグループ)に対してより効率的なインデックスを設定できます。 3番目に、主キーと外部キー、および制約を使用して、データの整合性を適用できます(これは、正規化の部分で部分的にカバーされています...)。最後に、RDBMSはテーブルを結合し、必要なデータを取得するための効率的なクエリプランを作成するのに非常に適しています。

毎年別々のテーブルを保持することに関しては、これはパーティショニングによって達成できます(最近のPostgreSQLバージョンでは重要な改善が行われています)。それを行う必要があるかどうかはわかりません-それはそもそもデータ量に依存しますが、他の要因にも依存します。 transactionテーブルをパーティションとして作成することもできますが、少なくともバージョン11以降を使用することを選択した場合は、デフォルトのパーティションが1つだけです。この場合、必要に応じて、年次パーティションを後で追加することを決定できます。

9
dezso