Какая оптимальная структура для таблицы «лайков»?
Если, чисто теоретически представить, что пользователей миллионы, а постов десятки миллионов, является ли такая структура оптимальной?
Почти. Нужно применить дублирование и прокинуть в эту таблицу сразу все те поля, которые вам могут пригодиться для отображения, иначе каждый раз придется делать join, чего бы не хотелось при highload. То есть нужно добавить в таблицу сразу поля вроде user_name, post_title, post_body, и т.д(в общем все то, что вы планировали доставать с помощью join).
На счет "пользователей миллионы, а постов десятки миллионов":
Если у вас будет такое количество данных, то вам в любом случае в какой-то момент придется прибегнуть к горизонтальному шардингу, поэтому если считаете что проект реально может дорасти до такого количества данных лучше сразу учесть это и спроектировать базу данных так, чтобы горизонтальный шардинг не стал проблемой.нужно ли тут поле id, или PK сделать составной (post_id, user_id) или PK вообще не нужен? Это влияет на селект?
Зависит от сценариев использования(подумайте, в каком случае вам нужно будет поле id), но в большинстве случаев оно не нужно и такие поля вводят для душевного спокойствия и гармонии. На селект это не влияет, ведь все равно вы будете делать выборку либо по user_id либо по post_id(опять же, это в большинстве распространенных сценариев, если у вас есть какая-то логика, где нужно будет выбирать из таблицы likes записи по какому-то намеренно введенному идентификтаору, то вводите).
Всплывала похожая проблема, именно с лайками.
Тормоза были из-за корявого кода.
Так как кол-во юзеров было уже под 2млн, постов у каждого от 1к до 30к,лайки соотвественно у каждого поста.
Надо было показывать выборку юзеров с накопленными лайками.
Решили сделать на клиенте)))
Посетитель выбирает массив юзеров, ему быстро отдаем основные данные, а ВЕСЬ МУСОР (лайки,шмайки, баллы) подгружаем отдельным (практически плоским мгновенным запросом) в фоне аяксом.
Нафига тащить сразу ВСЁ?...