Схема некорректна: в posts вы создаете поля для связи с журналами. А если статья сразу в 30 журналах будет, Вы будете 30 полей создавать?
Помимо этого включение в «where» условия отбора через оператор «or» может в некоторых случаях привести к катастрофическому падения производительности.
Правильно:
posts: p_id, text, date
posts_rel_journals: p_id, j_id
journals: j_id
follows: u_id, j_id
Запрос:
select posts.* from posts where p_id in
(select p_id
from posts_rel_journals
join follows on follows.u_id = 1 and follows.j_id = posts_rel_journals .j_id)
На таблицы связи ключи должны включать оба поля:
posts_rel_journals: primary_key (p_id, j_id)
follows(u_id, j_id)
Не бойтесь вложенных запросов: они ужасны, если используются в списке полей для ответа, но в условиях выбора (то бишь после where) и независимости от внешнего запроса (нет ссылки на таблицы внешнего запроса) они слабо влияют на производительность (по сути, оптимизатор все равно приведет его к наилучшей форме).
В данном случае поиск идет только по индексированным полям, поэтому запрос отработает быстро.
Если Вы принципиально хотите избавиться от distinct (или операции in), то должны создавать дубликаты статей для каждого журнала, тогда и проблемы с выборкой не будет (хотя будет забиваться жесткий диск. Впрочем, если дублей мало, то это непринципиально)