まず、お読みいただきありがとうございます。私が直面している問題を解決するためのアプローチのアイデアを持っています。それは、より適切に言えば要件です。以下に示すのは、現実のものではありませんが、機密情報を漏らさずに問題を表す架空のシナリオです。
ある国に住む人々の非常に大規模なデータベース、たとえば 1 億件のレコードを持つサービスを想像してみてください。
このサービスは、さまざまな企業がそれらの人々に関するデータを照会するために使用されています。通常のクエリは次のとおりです。
- x 市に住んでいる 25 歳から 30 歳までのすべてのカトリック教徒を表示してください
- 子供が 2 人以上いる人を表示
- 年収10万~20万の人教えて
- 昨年 3 回以上休暇を取った人を教えてください。
"People" (すごい..) という大きなテーブルがあり、1 億件のレコードすべてと、さまざまなフィールドに必要なすべての属性が含まれています。たとえば、40 列あるとしましょう (int、datetime、varchar、char などの組み合わせ.. ) 説明を取得したり、より複雑な属性を解決するためにメイン テーブルが参照する静的テーブル (25) も多数あります。
このデータベースを所有する会社は、Web サービスを介してこの DB にクエリを実行する機能を提供および販売しています。この Web サービスは、クエリ、クライアント ID、パラメータなどを受け取り、「できるだけ早く」結果セットを返す必要があります。
これまでのところ問題はありません。
このデータベースを所有する会社には、商用チームが管理する内部アプリケーションがあり、そこでは、各クライアントが x または y データにアクセスする機能を定義するさまざまなルールが設定されています。アクセスするデータが増えるほど、サービスに支払う金額も増えます。
すべてのクライアントがすべてを見ることができるわけではありません.一部のクライアントは特定の都市の人々のみを照会できます.他のクライアントは特定の年齢層の人々を見ることが許可されています,他のクライアントは特定の宗教「および」特定の社会経済レベルの人々など.
この DB を所有する会社は、毎日、必要に応じて上記のルールを変更し、クライアントがより多くまたはより少なく表示できるようにすることができます。所有者は、明日適用されるように今日変更することしかできません。同じ日やリアルタイムなどではありません。
したがって、この大きなデータベースは 1 つだけで、すべてのクライアントに対して、すべてのクライアントがあらゆる種類のクエリを作成しますが、システムは 2 つのレベルでデータを動的にフィルター処理する必要があります。
FIRST - 各クライアントが表示できるものを定義するビジネス ルールに基づく
SECOND - クエリのパラメーターに基づく (WHERE 句)
私の質問は、上記の「FIRST」動的フィルターを効率的に実装する方法です。
次のようないくつかのオプションがあります。
オプション 1 : クライアントごとにメイン テーブルのコピーを 1 つ用意し、1 日 1 回そのテーブルを切り捨て、メイン テーブルからレコードを再度挿入して、フィルタリング ルールをチェックし、クライアントが表示できるレコードのみを挿入します。このオプションは、クエリ パフォーマンスの観点からは優れていますが、処理時間の点では悪く、クライアントが増えると拡張性が低下します。テーブルと挿入が増え、処理時間が長くなります。そして、それは...醜いです..それは好きではありません.. :)
オプション 2 : ビジネス フィルタリング ルールを各リクエストの where 句に動的に追加します。大規模なバッチ プロセスを必要としないので良いですが、所有者がクライアントに対して定義できるフィルタリング ルールの数に制限がないため、where 句が長すぎる可能性があり、問題が発生する可能性があるため、好きではありません。 、およびフィルターは非常に複雑になる可能性があります(たとえば、会社Aは、70〜80歳で生まれ、ブロンドの髪を持ち、家族に1〜2台の車を持っている白人、「または」、黒人などにのみアクセスできます.. "または" bla bla.. "or" ) だから.. 要点はわかりますが、好きではありません。
オプション 3 : 私が考えていたのは、Row-Client などと呼ばれるテーブルを用意することです。これには、RowID とアクセスできるクライアントが含まれます。次に、ビジネス ルールに基づいてそのテーブルにデータを入力するバッチ プロセスが必要になります。(ただし、2 つの値しか挿入していないため、大きなプロセスではありません) 次に、クエリごとに、そのテーブルに結合を追加して、リクエストを実行している現在のクライアントに許可されている行のみを取得します。
次のようになります。
行: 1 クライアント: 1 行: 1 クライアント: 2
または(参照intはありません)
行: 1 クライアント: 1,2
または、その「クライアント」列をメイン テーブルに直接追加することもできます。
したがって、私の質問は、オプション 3 が機能するかどうか (1050 人のクライアントが営業時間について 1 日に 50 回クエリを実行する場合)、または効率的な方法でそれを達成するための他のアイデアや確立された方法、アプローチ、または技術を知ることです。
もちろん、私はあなたの質問/アイデアを受け入れており、あなたの助けに感謝しています.
クエリの実行後に結果セットからデータを削除することはできません。グループ化または集計操作が既に実行されているためです。
私が探しているのは、もちろんバッチ処理時間とクエリ応答時間を最小限に抑えることです。敬具