2013-06-11 24 views
7

最近、私はMySQLデータベースに履歴データを保存するベストプラクティスについて考えています。現時点では、各バージョン対応テーブルには、valid_fromvalid_toの2つのカラムがあり、いずれもDATETIMEタイプです。現在のデータを含むレコードの作成日はvalid_fromです。この行を更新すると、valid_toに更新日が入力され、valid_fromという新しいレコードが前の行のvalid_toと同じものになります。しかし、テーブルが非常に速くてデータを取得するのが非常に遅くなることがわかっています。
履歴データを保存する習慣があるかどうかを知りたいですか?MySQLデータベースの履歴データのベストプラクティス

+2

アーカイブを実行します。つまり、履歴データを別のテーブルに移動し、現在のテーブルを最新の状態に保ちます。 –

+1

@PradeepPatiこれは、履歴データと現在のデータの両方を選択できるクエリが必要な場合、アプリケーションを非常に複雑にします。しかし、彼は履歴テーブルと現在のテーブルを「マージ」するためにいくつかのビューを作成することができます。 – Kamil

+0

@カミルそれは本当に何かを複雑にしないで、むしろアプリを正常に保つ。あなたは履歴が必要です、あなたは履歴テーブルに行きます、現在のデータが必要です、現在のテーブルに移動します。 –

答えて

7

"大きな"テーブルとパフォーマンスについて心配するのはよくある間違いです。インデックスを使用してデータにアクセスすることができれば、1000000レコードのうち1000レコードがあるかどうかは重要ではありません。少なくとも、測定できるようにはなりません。あなたが言及しているデザインは一般に使用されています。時間がビジネスロジックの重要な部分であるのは素晴らしいデザインです。

たとえば、顧客が注文した時点での商品の価格を知りたい場合、valid_from < order_dateとvalid_untilがnullまたはorder_dateのいずれかである商品レコードを検索することができる最も簡単なソリューションです。

これは必ずしもそうではありません。アーカイブの目的のためだけにデータを保持する場合は、アーカイブテーブルを作成する方が理にかなっています。しかし、が実際にというビジネスロジックの一部ではないことを確認する必要があります。そうでなければ、複数のテーブルを検索することの苦労が大きくなります。製品テーブルまたはproduct_archiveテーブルを検索する度に注文が発注された時点での製品の価格について。

0

これは完全な答えではなく、ほんの少しの提案です。

is_validのようなインデックス付きブール型フィールドを追加できます。これにより、過去のレコードと現在のレコードを含む大きなテーブルのパフォーマンスが向上します。

一般的には、履歴データをseprateテーブルに格納するとアプリケーションが複雑になることがあります(現在の履歴レコードと履歴レコードが混在したデータを取得すると思われる複雑なクエリを想像してください)。

今日のコンピュータは本当に高速です。私はあなたが単一のテーブルと過去のレコードのための別のテーブルとのパフォーマンスを比較/テストする必要があると思います。

さらに、データベースを設計する方法を決定するために、大きなテーブルを持つMySQLがどれだけ高速であるかを確認するためにハードウェアをテストしてみてください。 MySQLの設定を調整することができます(キャッシュ/ RAMの増加から始まります)。

0

私はまさにこれを行うアプリケーションの完了に近づいています。私のインデックスのほとんどは、キーフィールドで最初にインデックスを作成し、現在のレコードに対してNULLに設定されているvalid_toフィールドを使用することで、現在のレコードを簡単かつ即座に見つけることができます。私のアプリケーションのほとんどはリアルタイム操作を扱うので、インデックスは高速なパフォーマンスを提供します。一度は誰かが履歴レコードを見る必要があり、その場合はパフォーマンスヒットがありますが、テストではそれほど悪くはありません。なぜなら、ほとんどのレコードは生涯にわたって多くの変更がないからです。

現在のレコードよりも多くの有効期限が切れているレコードがある場合は、より前のインデックスに支払うことがあります。キーフィールドの前に。

関連する問題