Абстрактно в худшем случае получается вот такой SQL:
select * from (
select p.*,
case when p.access_level in ('all') then 1
when p.access_level in ('registered') and $current_user_id>0 then 1
when p.access_level = 'groups' and pa.user_id is not null then 1
when p.access_level in ('friends') and uf.friend_id is not null then 1
else 0 end is_granted
from posts p,
left join posts_access pa
on p.post_id=pa.post_id
and p.access_level='groups'
and pa.user_id=$current_user_id
left join user_friends uf
on p.user_id=uf.user_id
and uf.friend_id=$current_user_id
) where is_granted=1
При условии что posts_access это денормализованная таблица групп-пользователей.
Ну и в зависимости от того вошел пользователь или нет, sql будет деформироваться. Если не вошел — будет простой запрос к posts с фильтрами и без лишних join'ов.
Да, так и сделаю, пожалуй) спасибо, ставлю «решение»
интересно. но получается, что если автор выбрал доступ groups, то мне надо по id автора посмотреть какие группы у него есть, и в какие из них вхожу я (как человек открывающий страницу). Т.е. надо делать join между автор-группы_автора и группы_автора-члены_групп. Причем эти join'ы будут даже если уровень доступа стоит НЕ groups. Не хочу лишние два джойна каждый раз :) Возникает желание денормализовать отношение группы-членыучастники чтобы сразу наложить еще и фильтр по участник_id=мой_id
И я вообще не хочу делать этот join если пользователь незарегистрирован или не вошел в систему, так что буду отрезать лишнюю часть запроса в PHP если это так.
Не нравится только то, что если меня включили в две группы, и им обеим разрешен доступ, то я получу задубленные строки. Надо еще distinct добавлять =\ но, видимо, тут никуда не деться…
При условии что posts_access это денормализованная таблица групп-пользователей.
Ну и в зависимости от того вошел пользователь или нет, sql будет деформироваться. Если не вошел — будет простой запрос к posts с фильтрами и без лишних join'ов.
Да, так и сделаю, пожалуй) спасибо, ставлю «решение»