0

私のウェブサイトには、スレッドを開始したり、スレッドに返信したり、投稿を削除したり、他の人の投稿を報告したりできるフォーラムがあります。

抽象化を行い、、(すべてのアクティビティに共通するフィールド)、およびアクティビティのタイプ(スレッド、応答、レポート、削除)と(それぞれに対応する)activityを格納するというテーブルを作成することにしました。テーブル)。user_idtimeeffective_idid

当初、これは優れたアイデアのように思われました。冗長性を回避し、各テーブルに問い合わせることなく、特定のユーザーが行ったことを簡単に検索できるようになるためです。しかし同時に、この抽象化はより複雑なクエリをもたらし(たとえばINNER JOIN、ほとんどすべての単純なクエリで使用する必要があります)、今ではより複雑なクエリで問題が発生しています。

だから私の質問は:私は正しい決断をしましたか?非常に高価なクエリが発生したとしても、実際の環境では完璧なデータベースを作成することが非常に重要ですか?

4

4 に答える 4

1

リレーショナルデータベースシステムの要点は、データを(正しいテーブルのエンティティを分離することによって)関連付けることです。そうすることで、結合を導入します。これは正常であり、優れたデータベース設計手法です。

多くのデータベース初心者は、結合を避け、さまざまなエンティティから属性を追加して、INNER結合を行わなくても済むようにしようとしますが、これは適切な手法ではなく、長期的には問題になります。結合には理由があり、データを関連付ける必要がある場合に使用する必要があります。

あなたの例では、本質的に「ログ」ファイルを作成しています。アプリケーションでのアクティビティは、ユーザーが行っていることへの単なるログです。投稿のログ、レポートのログ、削除のログ、さらに多くのログテーブル、またはユーザーが開始したアクティビティに関するreferenceIDを持つ1つの単純なログテーブル(これは実際にはFKです)。答えは、外部キーを含む1つのログテーブルで、ユーザーが開始した内容(削除、追加、フラグなど)を把握できるようにすることです。

ただし、自分自身に問いかけたいのは、ユーザーが単にこのデータを取得したいのに、なぜアクティビティ情報を表示するのかということです。このデータはいつでも正規化しておくことができますが、必要な場合にのみ選択してください。なぜこのアクティビティテーブルに参加しているのかわかりません。

于 2012-11-27T20:14:58.020 に答える
1

3〜5年前と同じ方向に進んでいたと思いますが、今では、より正規化されたアプローチを採用するのではなく、説明するアクティビティに対して、よりシンプルでフラットなデータベース設計を採用したいと思います。

CQRSとタスクドリブンUIの使用と理解は、これを実現するのに本当に役立ちました。ただし、状況に関係しない場合もあります。

基本的に、挿入、更新、削除が非常に効率的になるようにデータベースを最適化するために使用しましたが、これにより、単純な選択のために多くのテーブルを結合することになります。問題は、80%の確率で、ユーザーが選択したいということです。したがって、ユーザーが大部分の時間行うことに対してデータベース構造を最適化することは、アプリケーションの全体的なパフォーマンス、そして私の意見では、システムの保守と拡張性に本当に役立ちます。

私はあなたのアプリケーションとあなたがやろうとしていることについていくつかの仮定をしていますが、私には、アクティビティテーブルはキューから供給され、キューを監視している別のワーカープロセス/スレッドによって構築される可能性があるもののように聞こえます作業項目用。これらの作業項目(コマンド??)が見つかると、ワーカープロセスはデータをフラット化し、適切なアクティビティテーブルを更新します。アクティビティテーブルをクエリするときは、基本的に単純なことをしていることになりますSELECT * FROM ACTIVITY(ただし、クエリはお勧めしませんSELECT *。列に名前を付けてください)。したがって、アクティビティテーブルの挿入/更新にヒットしますが、選択したパフォーマンスは優れています。

これがお役に立てば幸いです。

于 2012-11-27T20:20:27.340 に答える
1

あなたの質問から、あなたの目的がすべての活動の共通の特徴を分割することであったのか、そして複雑なクエリがあなたにどのように問題を与えているのかはわかりません。

アクティビティのタイプ(スレッド、応答、レポート、削除)の説明は、クラスおよびサブクラスとも呼ばれるタイプおよびサブタイプの古典的なケースのように見えます。この場合、単一テーブル継承とクラステーブル継承として知られる2つの古典的なデザインパターンがあります。これら2つのデザインパターンにはタグがあります。別のデザインパターンである共有主キーがあります。これは、クラステーブル継承と組み合わせて効果的に使用できます。

STIからCTIへの移行には、テーブルの分解が含まれます。これは、説明した分解と似ています。SPKを使用すると、特殊なサブクラステーブルごとに個別のIDフィールドが不要になり、個別のタイプフィールドも不要になります。これにより、苦労してしまったクエリよりも単純なクエリが生成される可能性があります。それらのクエリを見ずに知ることは不可能です。

この分解は、標準の正規形2NFから5NFのいずれかに準拠するという意味で、「正規化」ではないことに注意してください。しかし、これらの通常の形式は、とにかくクエリの単純さではなく、更新の単純さに関係しています。

データの使用方法を考慮して、優れた設計が行われます。時々私たちは途中でそれを学びます。完璧なデザインがどのようなものかわかりません。私たちは常にトレードオフに関与していると思います。

于 2012-11-28T02:46:28.293 に答える
0

データベースの非正規化について考えたことはありますか?詳細については、http://en.wikipedia.org/wiki/Denormalizationを参照してください。

于 2012-11-27T20:14:33.490 に答える