質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

1回答

1732閲覧

DBで世代管理する時、出来るだけ無駄なデータを増やさないようにしたい

退会済みユーザー

退会済みユーザー

総合スコア0

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

0グッド

1クリップ

投稿2022/08/04 08:12

前提

例えば、下記のマスターと売上テーブルがあるとします。
また、世代は、2→3→4と、毎日のように新しい世代がINSERTされます。
※雑な例なので、売り上げデータの主キーが重複してるんじゃ?とかは無視して下さい・・・

世代マスター

世代NO登録日時最終編集日時
12022-01-01 12:00:002022-01-02 16:00:00
22022-01-02 13:00:00null
32022-01-03 12:00:002022-01-05 12:00:00

従業員マスター(主キーは、従業員CDと世代の複合主キー)

従業員CD氏名連絡先世代
EM0001岡本 和真0000-00-00001
EM0002吉川 尚輝0001-01-00011
EM0003丸 佳浩0002-02-00021

商品マスター(主キーは、商品コードと世代の複合主キー)

商品コード商品名単価世代
CD0001商品110001
CD0002商品215001
CD0003商品320001

売上データ ( トランザクションデータ )

売上CD商品コード商品名単価数量合計金額登録者CD世代
S0001CD0001商品1100022000EM00011
S0001CD0002商品2150011500EM00011
S0002CD0002商品2150046000EM00021
S0002CD0003商品3200024000EM00031

必要機能

過去に登録されたトランザクションデータ(上記でいえば売上データ)に誤りがあれば、当時のマスターを修正した上で、
トランザクションデータに反映させたいのです。

※例えば、世代1の時の、従業員CD:EM0001の方の名が「和真」は誤登録で、本当は「一馬」であり、「一馬」に修正した場合、
売上データ (売上CD S0001)の登録者CDで登録者名を参照した場合、下記の状態にしたいのです。
修正前:岡本 和真 が表示される。
修正後:岡本 一馬 が表示される。

悩んでいる点

指定した世代のマスターを元に、その世代のマスターを元に登録されたトランザクションデータを修正したいので、
全世代の全データを保管する必要があり、どれかのテーブルに新世代が追加されると、
変更されていないテーブルも、変更されていないデータを新世代として追加する必要が出てきます。
※変更されていないテーブルも、常に変更対象候補でありつづける為。

そうするとデータ量が膨大になってしまいます。

全ての世代の全てのデータを1つのテーブルに登録すると、1カ月で1億レコードを軽く超えるようなテーブルが大量生産されます。

現行世代用のテーブルと過去世代用のテーブルを分離した場合でも、過去テーブルはどんどん肥大化していきます。

データの肥大化を避けるために、どのような設計にするべきでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

logres_Fan

2022/08/04 12:16

 まず、教えて下さい。(世代別)従業員マスタに新しい従業員を登録する場合、世代マスタを検索、登録日のレコードが存在すれば世代Noを参照値とする、無ければ世代マスタに新しい登録日を追加・新しい世代Noを参照値とする。(世代別)商品レコードも同様に処理する。このような認識で合っていますか?  次に、「どれかのテーブルに新世代が追加されると、変更されていないテーブルも、変更されていないデータを新世代として追加する必要が出てきます。」について教えて下さい。「世代マスタに新世代が追加される度に、既存の従業員全てと既存の商品全てを新世代として各マスタに新規登録する。」という事でしょうか?
guest

回答1

0

通常、マスターデータと履歴データは別のテーブルに、マスターテーブルと履歴テーブルに分けます。
WHERE句でPRIMARY KEY に対して = イコールでSELECTできるのでパフォーマンスは良いです。
従業員CDと世代をPRIMARY KEYにすると範囲検索になってしまうので、SQLが複雑になるし、パフォーマンスが落ちます。
トランザクションデータには商品名や従業員名は持たずに、必要ならマスターとSELECT ... JOIN ...で取得します。

実際にCREATE TABLEとINSERTでデータを用意してSQLを書いてみては?質問は修正できます。

なお、個人的に15年以上前ですが、マスターと履歴を同じテーブルで設計する主義って人に会ったとこがあります。破綻するところを見たくなかったので、わたしは3ヶ月で契約を終えました。

投稿2022/08/04 08:35

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問