一連の場所と一連の年のビジネス数値を格納するビジネス インテリジェンス システムのデータベース モデルを設計する予定です。
これらの数値の一部は、同じ年と同じ場所の他の数値から計算する必要があります。以下の文章では、計算されていない数値を「基礎数値」と呼びます。基本的な数値を格納するには、これらの列を含むテーブル デザインが適しています。
| year | location_id | goods_costs | marketing_costs | warehouse_costs | administrative_costs |
このテーブルを使用して、他のすべての必要な数値を計算するビューを作成できます。
CREATE VIEW all_figures
SELECT *,
goods_costs + marketing_costs + warehouse_costs + administrative_costs
AS total_costs
FROM basic_figures
次の問題に遭遇しなければ、これは素晴らしいことです。
- ほとんどのデータベース (私が使用する予定の MySQL を含む [編集: しかし、私はバインドされていません]) には、ある種の列数または行サイズの制限があります。多くの数値を保存する必要がある (そしてさらに計算する必要がある) ため、この制限を超えてしまいます。
- 新しい数値を追加する必要があることは珍しくありません。(図を追加するには、テーブルのデザインを変更する必要があります。通常、このような変更はパフォーマンスが低いため、テーブルへのアクセスが非常に長い間ブロックされます。)
- また、説明や単位など、各図の追加情報も保存する必要があります (すべての図は 10 進数ですが、US$/EUR の場合もあれば、% の場合もあります)。何か変更があった場合、basic_figures テーブル、all_figures ビュー、および Figure 情報を含むテーブルがすべて正しく更新されていることを確認する必要があります。(これは、技術/実装の問題というよりも、データの正規化の問題です。)
~~
したがって、このテーブル設計を使用することを検討しました。
+---------+-------------+-------------+-------+
| year | location_id | figure_id | value |
+---------+-------------+-------------+-------+
| 2009 | 1 | goods_costs | 300 |
...
このエンティティ属性値のような設計は、これら 3 つの問題に対する最初の解決策になる可能性があります。ただし、計算が面倒になるという新たな欠点もあります。本当に面倒です。
上記のようなビューを作成するには、次のようなクエリを使用する必要があります。
(SELECT * FROM basic_figures_eav)
UNION ALL
(SELECT a.year_id, a.location_id, "total_costs", a.value + b.value + c.value + d.value
FROM basic_figures_eav a
INNER JOIN basic_figures_eav b ON a.year_id = b.year_id AND a.location_id = b.location_id AND b.figure_id = "marketing_costs"
INNER JOIN basic_figures_eav c ON a.year_id = c.year_id AND a.location_id = c.location_id AND c.figure_id = "warehouse_costs"
INNER JOIN basic_figures_eav d ON a.year_id = d.year_id AND a.location_id = d.location_id AND d.figure_id = "administrative_costs"
WHERE a.figure_id = "goods_costs");
それは美しさではありませんか?これは 1 つの Figure に対するクエリにすぎないことに注意してください。他のすべての計算された数値 (上で書いたように多数あります) も、このクエリで UNIONed する必要があります。
~~
私の問題についてのこの長い説明の後、私は実際の質問を締めくくります:
- どのデータベース設計を提案しますか? / 上記の 2 つのデザインのいずれかを使用しますか? (「はい」の場合、それはなぜですか?「いいえ」の場合、その理由は?)
- まったく別のアプローチの提案はありますか? (私は非常に感謝しています!)
- 結局、データベースは実際に計算を行うものである必要がありますか? 計算をアプリケーション ロジックに移動し、結果を単純に格納する方が理にかなっていますか?
ところで、私はすでに MySQL フォーラムで同様の質問をしました。ただし、回答が少しまばらであり、これは単なる MySQL の問題ではないため、質問を完全に書き直してここに投稿しました。(したがって、これはクロスポストではありません。) スレッドへのリンクは次のとおりです。