トレードオフについての質問です。
ソーシャルネットワークを想像してみてください。各ユーザーにはステータス メッセージがあり、いつでも変更できます。彼がそれを変更するときはいつでも、彼のすべての友人は壁を通して通知されます (Facebook のように)。
これを機能させるには。Users(id, name)、FriendLists(userId、friendUserId)、Notifications(?) の 3 つのテーブルがあります。
ここで、各ユーザーのフレンド リストに約 50 人のフレンドがいるとします。私はジレンマに直面しています - 通知テーブルを実装する方法。
最初のオプション
CREATE TABLE Notifications
(
toUserId bigint NOT NULL,
[identity] bigint IDENTITY(1,1) NOT NULL,
fromUserId bigint NOT NULL,
data varchar(256) NOT NULL,
CONSTRAINT [PK_Notifications] PRIMARY KEY CLUSTERED (toUserId, [identity])
)
通知を送信:
-- Get all friends of @fromUserId.
WITH Friends AS
(SELECT FriendLists.friendUserId
FROM FriendLists
WHERE userId = @fromUserId)
-- Send updates to all friends.
SELECT
friendUserId as toUserId,
@fromUserId as fromUserId,
@data as data
INTO Notifications
FROM Friends
この場合、ステータスの変更ごとに 50 のレコードを作成します (50 人の友人を想定)。これは悪いです。ただし、良い点は、toUserId にクラスター化されたインデックスがあるため、特定のユーザーの通知を取得するのが非常に高速であることです。
2番目のオプション
CREATE TABLE Notifications
(
toUserId bigint NOT NULL,
[identity] bigint IDENTITY(1,1) NOT NULL,
fromUserId bigint NOT NULL,
data varchar(256) NOT NULL,
CONSTRAINT [PK_Notifications] PRIMARY KEY CLUSTERED ([identity])
)
CREATE NONCLUSTERED INDEX [IX_toUserId] ON Notifications (toUserId ASC)
通知を送信:
-- Get all friends of @fromUserId.
WITH Friends AS
(SELECT FriendLists.friendUserId
FROM FriendLists
WHERE userId = @fromUserId)
-- Send updates to all friends.
INSERT INTO Notifications(toUserId, fromUserId, data)
VALUES(friendUserId, @fromUserId, @data)
ここでは、ステータス更新ごとに 1 つのレコードのみを挿入します。これはいい。悪い点は、toUserId によってレコードがクラスター化されていないため、通知の取得が遅くなることです。
通知の取得は、両方の方法で同じです。
SELECT TOP(50) fromUserId, [identity], data
FROM Notifications
WHERE toUserId = @toUserId
それで、あなたはこれについてどう思いますか?