2010-07-26 1 views
0

То, что я пытаюсь достичь, является сложной процедурой конфиденциальности, у меня есть следующие таблицы.Как применить настройки конфиденциальности в сообщениях, появляющихся в ленте новостей с MySQL?

сообщений

posts_privacy

privacy_global

followerlist

У нас есть ленты новостей такие вещи на нашем сайте, который получает сообщения 10 latests от людей, пользователь следующих, есть 3 уровня конфиденциальности, сначала privacy_global, где пользователь может установить параметры конфиденциальности в своих сообщениях, 0, 1 и 2 для «Только меня», «Все», «Только последователи», затем есть posts_privacy, где пользователь Калифорния n выберите список людей, которых он хочет показать или скрыть сообщение, прежде чем публиковать его, этот параметр отменяет параметры privacy_global и posts_privacy, если они установлены.

теперь моя проблема в том, что, когда я применяю конфиденциальность в ленте новостей, используя php, я в основном прошу сообщения, подобные этому.

SELECT `post`.*, 
    `users`.`fullname`, 
    `users`.`username`, 
    `posts_privacy`.`hide`, 
    `posts_privacy`.`show`, 
FROM `post` 
    LEFT JOIN `posts_privacy` ON `post`.`id`=`posts_privacy`.`postid` 
    INNER JOIN `users` ON `post`.`userid` = `users`.`id` 
WHERE (`post`.`userid` IN (1,2,3,4,5,6) 
AND 12 NOT IN (
    SELECT `hide` FROM `posts_privacy` WHERE `postid`=`post`.`id`) 
    OR `show`= 12 
) 

GROUP BY `post`.`id` 
ORDER BY `time` DESC LIMIT 10" 

Я не могу понять, как применить все другие условия, до этого я использовал другой запрос и возвращает сериализованные массивы людей, что пост должен быть скрыт или показано, затем сериализации и обработал его в PHP и удалил это сообщение из массива перед отправкой в ​​браузер, который создал отверстие в ленте новостей, вместо того, чтобы загружать 10 сообщений, появляется только 6 сообщений, потому что php удалил 4, у которых была конфиденциальность, прежде чем они попали в браузер, моя цель здесь нужно ВСЕГДА соблюдать все условия конфиденциальности в SQL до того, как сообщения покинут базу данных, поэтому у меня нет этой проблемы с подсчетом сообщений в ленте новостей.

Я попытался изучить функции и процедуры MySQL, но мне сказали, что они не могут обрабатывать запросы или возвращать таблицы.

любые советы относительно того, как подойти к этой проблеме?

EDIT: Если это помогает, система, которую я пытаюсь сделать, аналогична той, что есть на Facebook, где пользователь может установить конфиденциальную конфиденциальную информацию, но также имеет глобальные настройки, которые перегружаются, когда это будет сделано.


Структура таблиц:

followerslist:

ID PRIMARY KEY BIGINT (20)
Идентификатор_пользователя BIGINT (20) < < идентификатор пользователя, который нажимает кнопку Следование
targetid BIGINT (20) < < ID пользователя, которому следует

p ОСТ:

ID ПЕРВИЧНЫЙ КЛЮЧ BIGINT (20)
содержание ТЕКСТА
Название VARCHAR (100)
время DATETIME
идентификатор пользователя BIGINT (20)

posts_privacy:

ID ПЕРВИЧНЫЙ КЛЮЧ BIGINT (20)
postid BIGINT (20)
скрыть BIGINT (20)
показать BIGINT (20)

+0

Можете ли вы показать структуру соответствующих таблиц - только важные поля будут делать. Какова связь между «followerlist» и другими таблицами - это просто список идентификаторов пользователей, связанных с каждым пользователем? – Mike

+0

Да в значительной степени его просто так, у него есть идентификаторы последователей и человека, которому следует следовать. –

+0

Столбцы 'hide' и' show' в таблице 'posts_privacy' содержат значение' users.id'? – Mike

ответ

1

Ниже представлен один из способов получения результатов, которые вы после. Однако вам нужно будет провести тщательное тестирование, поскольку у меня не хватило времени, чтобы пойти дальше. Он основан на перспективе зрителя - пользователя, который запрашивает сообщения, для которых у них есть разрешение на просмотр. Это не идеально, поэтому, пожалуйста, рассматривайте его как нечто, из которого можно построить.

Некоторые из полей, что запрос возвращает не будут необходимы в окончательном варианте, но они удобны для тестирования:

SET @viewerid := 5; 
SELECT 
    p.id AS post_id, 
    owner.id AS owner_id, 
    pg.privacy AS privacy_global, 
    pp.hide AS hide_from, 
    pp.show AS show_to, 
    f.userid AS viewer, 
    f.targetid AS following 
FROM posts AS p 
JOIN users AS owner ON owner.id = p.userid 
JOIN privacy_global AS pg ON pg.postid = p.id 
LEFT JOIN posts_privacy AS pp ON pp.postid = p.id 
LEFT JOIN followerlist AS f ON f.userid = @viewerid 
WHERE ((pg.privacy = 0 AND pp.show = @viewerid) 
OR (pg.privacy = 1) 
OR (pg.privacy = 2 AND f.targetid = p.userid)) 
AND ((pp.hide != @viewerid OR pp.hide IS NULL) 
AND (p.userid != @viewerid)) 
GROUP BY p.id 
LIMIT 10; 

Во время тестирования вы можете найти полезным разбить запрос вниз. Следующий фрагмент перечисляет идентификатор поста, владелец пост, глобальные настройки конфиденциальности и скрытие от/шоу для идентификаторов пользователей:

SELECT 
    p.id AS post_id, 
    owner.id AS owner_id, 
    pg.privacy AS privacy_global, 
    pp.hide AS hide_from, 
    pp.show AS show_to 
FROM posts AS p 
JOIN users AS owner ON owner.id = p.userid 
JOIN privacy_global AS pg ON pg.postid = p.id 
LEFT JOIN posts_privacy AS pp ON pp.postid = p.id 

Добавить зрителя идентификатор пользователя и дополнительные строки будут показаны для каждой должности, где владелец что после отрабатывался зрителем:

SET @viewerid := 1; 
SELECT 
    p.id AS post_id, 
    owner.id AS owner_id, 
    pg.privacy AS privacy_global, 
    pp.hide AS hide_from, 
    pp.show AS show_to, 
    f.userid AS viewer, 
    f.targetid AS following 
FROM posts AS p 
JOIN users AS owner ON owner.id = p.userid 
JOIN privacy_global AS pg ON pg.postid = p.id 
LEFT JOIN posts_privacy AS pp ON pp.postid = p.id 
LEFT JOIN followerlist AS f ON f.userid = @viewerid; 

в WHERE пункты затем, чтобы сузить эти результаты на основе за пост и глобальных настроек конфиденциальности.

+0

Большое спасибо :) Я действительно искал что-то, на что я опишу, я попробую отсюда, вы действительно помогаете: D. –

+0

Я закончил задачу: D, все работает как ожидалось = D. –