Хочу отметить, что на данный момент у меня нет большого опыта по оптимизации SQl, поэтому возможно, что мой ответ наложит слишком большую нагрузку на сервер.
Я бы выбрал таблицу, скажем, photo_permission, которая будет содержать отображение между user_id и авторизованными photo_id для каждого идентификатора пользователя. Что-то вроде:
| user_id | photo_id |
| 1 | 1 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
Если существует запись для определенного пользователя с идентификатором user_id и определенной фотографии с идентификатором photo_id, у пользователя есть разрешение на просмотр фотографии.
Если вы не можете заблокировать фотографию от пользователя, который имеет доступ к группе, содержащей фотографию, вы можете даже упростить приведенную выше таблицу
| authority_id | authority_type | photo_id |
| 1 | group | 1 |
| 1 | user | 3 |
| 2 | user | 1 |
| 2 | group | 2 |
Теперь вы можете проверить, указан ли идентификатор пользователя в строках с пользователем author_type, ИЛИ проверить, равен ли его идентификатор IN (SELECT id FROM user where group_id=authority_id)
в строках с группой author_type. Обратите внимание, что приведенный выше код не проверен.