SQL Server: помощь в разработке таблиц - PullRequest
1 голос
/ 18 марта 2012

У меня есть приложение, которое отображает сообщения, и для каждого сообщения пользователи могут сказать, нравится им сообщение или нет. Для каждого поста я должен показать, сколько пользователей нравится и сколько не нравится. Предположим, у меня есть эти таблицы:

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, который возвращает отображаемые сообщения.

Любая идея приветствуется.

Ответы [ 2 ]

1 голос
/ 18 марта 2012

Я столкнулся с подобной ситуацией и выбираю стратегию А:

  • Размещение этой информации в основной таблице - это «нормальный» выбор, учитывая, что между Post и PostStat будут взаимно-однозначные отношения.
  • вам не нужно будет объединять таблицы Post и PostStats каждый раз, когда вы запрашиваете сообщения, что, как я полагаю, обходится дороже, чем доступ к одной таблице, содержащей одинаковые столбцы, разбросанные по двум.
  • если вы обновите счетчики «нравится / не нравится» с помощью триггера (это то, что я сделал), то наличие столбца в родительской таблице сделает жизнь намного проще ... На самом деле вам просто нужно написать « обновите запись set likes = likes + 1, где postId =: new.postId "(синтаксис oracle sql), а ссылочная целостность postId гарантирует, что у вас будет строка для обновления.

Зная, что записи не блокируют чтения (на самом деле они будут просто читать предыдущее значение, пока транзакция не будет завершена) Я сомневаюсь, что у вас будут проблемы с блокировкой, помещающие столбцы в основную таблицу.

1 голос
/ 18 марта 2012
I will have a DB with millions of posts

не думаю, что это достаточная причина для сохранения дубликатов данных в вашей БД.

У вас уже есть вся необходимая информация о ваших текущих таблицах. Это вопрос построения правильных индексов, и вы можете легко посчитать, сколько пользователей понравилось \ не понравилось сообщение.

Если вы действительно не согласны с этим подходом, я предлагаю реализовать опцию A с триггерами в таблице UserPostAction, чтобы сохранить ваши 2 новых столбца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...