(Подобный ответ Яну Ганчичу здесь, но я решил, что мой взгляд на рейтинг был достаточно другим ...)
Ваша первоначальная мысль об отдельной таблице для хранения лайков / дислайков - абсолютно то, что я хотел бы сделать. Я бы поместил индексы в два основных столбца (идентификатор игрока и идентификатор записи), что очень важно для следующего бита.
Например:
create table users (
userId varchar(254) not null,
-- ...
primary key (userId)
)
ENGINE=...;
create table posts (
postId int(11) not null,
title varchar(254) not null,
content text not null,
-- ...
primary key (postId)
)
ENGINE=...;
create table userPostRatings (
userId varchar(254) not null,
postId int(11) not null,
rating int(2) not null,
-- ...
)
ENGINE=...;
create index userPostRatings_userId on userPostRatings(userId);
create index userPostRatings_postId on userPostRatings(postId);
Затем я бы использовал объединенный запрос (будь то в хранимой процедуре, в коде или в представлении) для получения информации о публикации, например ::
select p.postId, p.title, p.content, avg(r.rating)
from posts p
left outer join userPostRatings r on p.postId = r.postId
where p.postId = ?
group by p.postId;
(Это вернет NULL
в среднем для всех сообщений, у которых еще нет оценок.)
Несмотря на то, что это соединение, из-за индексов в таблице userPostRatings
оно довольно эффективно.
Если вы обнаружите, что объединение убивает вас (сайты с очень высоким уровнем параллелизма), то вы можете немного отменить нормализацию, как предложил Ян, добавив столбец среднего рейтинга к posts
и обновляя его. , Вы просто изменили бы свой запрос, чтобы использовать его. Но я бы не стал начинать денормализованным, это больше кода и, возможно, преждевременная оптимизация. Ваша база данных находится там, чтобы отслеживать эту информацию; как только вы дублируете отслеживаемую информацию, вы сталкиваетесь с проблемами обслуживания и синхронизации. Это может быть оправдано в конце, но я бы не стал исходить из предположения, что моя БД не может помочь мне с этим. Внесение изменений (если вы планируете это заранее), если объединение является проблемой в вашей конкретной ситуации, не имеет большого значения.