NoSQL ソリューションに移行する前に、まずインデックス付きビューを試すことをお勧めします。
http://msdn.microsoft.com/en-us/library/ms187864.aspx
と:
http://msdn.microsoft.com/en-us/library/ms191432.aspx
インデックス付きビューを使用すると、ベース データを適切に正規化されたテーブルに保持し、データの整合性を維持しながら、そのデータの非正規化された「ビュー」を提供できます。トランザクションの多いテーブルにはこれをお勧めしませんが、書き込みよりも読み取りの方が重いとおっしゃっていたので、これが機能するかどうかを確認することをお勧めします。
2 つの例のテーブルに基づいて、1 つのオプションは次のとおりです。
1) 次のように定義された User テーブルに列を追加します。
TaskCount INT NOT NULL DEFAULT (0)
2) 次のように定義されたタスク テーブルにトリガーを追加します。
CREATE TRIGGER UpdateUserTaskCount
ON dbo.Task
AFTER INSERT, DELETE
AS
;WITH added AS
(
SELECT ins.UserID, COUNT(*) AS [NumTasks]
FROM INSERTED ins
GROUP BY ins.UserID
)
UPDATE usr
SET usr.TaskCount = (usr.TaskCount + added.NumTasks)
FROM dbo.[User] usr
INNER JOIN added
ON added.UserID = usr.UserID
;WITH removed AS
(
SELECT del.UserID, COUNT(*) AS [NumTasks]
FROM DELETED del
GROUP BY del.UserID
)
UPDATE usr
SET usr.TaskCount = (usr.TaskCount - removed.NumTasks)
FROM dbo.[User] usr
INNER JOIN removed
ON removed.UserID = usr.UserID
GO
3) 次に、次のビューを実行します。
SELECT u.UserID,
u.Username,
u.UserDisplayName,
u.TaskCount,
t.TaskID,
t.TaskName
FROM User u
INNER JOIN Task t
ON t.UserID = u.UserID
次に、上記のリンクの推奨事項 (WITH SCHEMABINDING、Unique Clustered Index など) に従って、「永続化」します。上記のように SELECT のサブクエリで集計を行うのは非効率的ですが、この特定のケースは、書き込みよりも読み取りが多い状況で非正規化することを目的としています。したがって、インデックス付きビューを実行すると、集計を含む構造全体が物理的に保存されるため、読み取りごとに再計算されません。
現在、一部のユーザーがタスクを持っていない場合に LEFT JOIN が必要な場合、それらの作成に関する 5000 の制限により、インデックス付きビューは機能しません。その場合、非正規化された構造である実際のテーブル (UserTask) を作成し、ユーザー テーブルのみのトリガーを介して入力することができます (上で示したトリガーを実行すると仮定します。 Task テーブル)、または User テーブルの TaskCount フィールドをスキップして、両方のテーブルに Triggers を設定して、UserTask テーブルに入力することができます。結局、これは基本的に、同期トリガーを記述する必要なく、インデックス付きビューが行うことです。