Громоздкость - это не критерий. Главное чтобы оптимизатору-планировщику было понятно как выполнять запрос.
Вот если запрос выполняется медленно - тогда думать надо.
Можно убрать констрэйн, но это чревато нарушением консистентности.
Можно в проекциях объектов (таблицах) делать условно избыточность в виде нескольких полей-ссылок и поле типа.
Естественно и то и то не идеал. Но так или иначе приходится искать компромисс между многомерностью (ООП) и ее проекциями (реляционные БД). Отсюда и различные вариант нереляционных БД
Без глубокого понимания стоит задать себе непреложное правило "у каждой таблицы должен быть primary key". В дальнейшем, когда-нибудь можно будет достичь нирваны ситуации когда pk не должно быть.
Представляю картину: ходит человек с мобилкой в роуминге, открывает сайтик, а ему вываливается сотня гигов данных, дабы потом жабаскрипт поискал там и нашел нужную сотню байт....
select
article_id,
count(distinct user_article_likes.article_id),
count(distinct subscribed_user_articles.article_id)
from articles
left join лайки
left join подписки
group by article
SELECT DISTINCT `mod_id` AS `mod`, '' AS `good` FROM `table1` WHERE `id` IN (...)
UNION
SELECT DISTINCT '' AS `mod`, `goods_id` AS `good` FROM `table2` WHERE `id` IN (...)