У меня есть приложение, которое отображает сообщения, и для каждого сообщения пользователи могут сказать, нравится им сообщение или нет.
Для каждого поста я должен показать, сколько пользователей нравится и сколько не нравится.
Предположим, у меня есть эти таблицы:
CREATE TABLE [dbo].[Post](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Quotation] [text] NOT NULL,
CONSTRAINT [PK_Post] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE TABLE [dbo].[UserPostAction]( --Every action of the user (like or dislike) is recorded to this table
[PostId] [bigint] NOT NULL,
[UserId] [bigint] NOT NULL,
[ActionValue] [int] NOT NULL, --Like / Dislike
CONSTRAINT [PK_UserPostAction] PRIMARY KEY CLUSTERED
(
[PostId] ASC,
[UserId] ASC,
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Каков наилучший способ, с точки зрения производительности, иметь оператор select, который возвращает список постов, который уже содержит статистику «нравится / не нравится»:
A) Добавьте еще 2 столбца в таблицу Post: TotalLike и TotalDislike, и при вставке новой записи в UserPostAction я обновлю эти столбцы? Таким образом, при выборе постов из таблицы постов у меня будет уже рассчитанная статистика.
B) Добавьте третью таблицу: PostStat ([PostId], [TotalLike], [TotalDislike]) и обновите таблицу в пакетном процессе. Оператор select будет использовать Inner Join on Post.Id = PostStat.PostId для получения статистики.
C) Любой другой способ мыслить.
Надеюсь, у меня будет БД с миллионами сообщений, и многие пользователи будут очень часто запрашивать таблицу сообщений.
Имейте в виду, что статистика обновляется очень часто, потому что многим пользователям нравится или не нравится много постов. Это означает (возможно) выполнение большого количества обновлений и блокировку таблиц, что будет мешать оператору select, который возвращает отображаемые сообщения.
Любая идея приветствуется.