Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Как лучше сделать выборку?


Автор: Gtaman 30.7.2006, 18:34
Столкнулся со следующей проблемой:

На форуме нужно определить, являеться ли пользователь модератором на форуме. Модераторы - группы, занесенные в список модераторов. Вот структура таблицы групп:

id | name

таблица членов группы:

group_id | user_id

таблица модераторов:

group_id | forum_id (Эту таблицу я планирую переделать под общую админку.... но смысл остаеться)

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

Код

$posts_query = mysql_query("SELECT * FROM forum_posts WHERE fid = '$_GET[fid]' AND tid = '$_GET[tid]'");
while($posts = mysql_fetch_array($posts_query)) /* выборка постов */
{
$moders_query = mysql_query("SELECT * FROM moders WHERE forum_id = '$posts[fid]' OR forum_id = 'all'");
$moders = mysql_fetch_array($moders_query);
$moder_ex = mysql_num_rows(mysql_query("SELECT * FROM groups_users WHERE group_id = '$moders[group_id]' AND user_id = '$_SESSION[your_id]'"));
if($moder_ex != 0)
{
// тут значения переменных для модераторов
$warning = "You are moderator!";
}
echo "$posts[message]<br>$warning<br>";
}
 

Автор: sayber 31.7.2006, 01:02
Gtaman, А непроще все было в одной таблице сделать и одним запросом проверять? 

Автор: Gtaman 31.7.2006, 01:56
sayber, ну уж тогда проще ваще не на пхп писать, а создавать хтмл странички вручную..... типа надо модератору пост скрыть - обращаеться ко мне, а хтмл файл редактирую......

У меня тут не только форум. И группы - не чисто форумное. Чел вообще может не состоять не в какой группе, может состоять в 100 группах....... 

Автор: sayber 31.7.2006, 02:58
У меня тоже самое. Разные группы для разных вещей. 
сайт+форум к примеру. 

Автор: Gold Dragon 31.7.2006, 06:55
Gtaman, что на выходе должно быть? Какие данные? Просто это всё можно сделать одним сложным запросом 

Автор: GiV 31.7.2006, 11:14
Код

$posts_query = mysql_query("SELECT * FROM forum_posts WHERE fid = '$_GET[fid]' AND tid = '$_GET[tid]'");
while($posts = mysql_fetch_array($posts_query)) /* выборка постов */
{
$qh= mysql_query("SELECT * FROM groups_users WHERE user_id = '$_SESSION[your_id]'");
$user = mysql_fetch_array($qh);
$moder_ex = mysql_num_rows(mysql_query("SELECT * FROM moders WHERE group_id='$user[group_id]' AND (forum_id = '$posts[fid]' OR forum_id = 'all'")));
if($moder_ex > 0)
{
// тут значения переменных для модераторов
$warning = "You are moderator!";
}
echo "$posts[message]<br>$warning<br>";
}
 

Автор: AntonioBanderaz 31.7.2006, 11:46

Цитата(GiV @  31.7.2006,  11:14 Найти цитируемый пост)
"SELECT * FROM forum_posts WHERE fid = '$_GET[fid]' AND tid = '$_GET[tid]'"

В корне не верно.  ты в SQL данные прям из гета кидаешь.... 

а SQL там вроде такой
Код

SELECT 
    tblUsers.`name` as moderName
FROM  `таблица модераторов` tblModers
    INNER JOIN `таблица членов группы` tblGUsers 
                 ON (tblModers.`group_id` = tblGUsers.`group_id`)
    INNER JOIN `таблица юзеров` tblUsers 
                 ON (tblGUsers.`user_id` = tblUsers.`id` AND tblUsers.`id` = 'userOUID')
WHERE 
    tblModers.`forum_id` = forumOUID OR tblModers.`forum_id` = 'ALL'


таблица модераторов связана с таблицей членов группы по group_id, которая в свою очередь связана с таблицей юзеров по (user_id = id)

если рекордсет не пустой то этот чувак есть модер если пустой то не модер. 

А вообще странная у тебя структупа БД. По хорошему надо немного не так. 

Таблица пользователей (М к N на роли и на группы ролей)
Таблица групп (со связкой M к N на таблицу пользователей  и  M к N на роли и группы ролей) 
Таблица групп ролей (со звязками M к N на роли)

Мой совет возьми какой-нидь Enterprise Architect и навояй свою базу. (UML - решает!!!) 

Автор: GiV 31.7.2006, 12:10
AntonioBanderaz, а почему мне кажется что два маленьких запроса будут работать быстрее чем один сложный с соединением таблиц?

И так для справки. Никогда не следует указывать в части ON какие бы то ни было условия, накладывающие ограничения на строки в наборе результатов. Если необходимо указать, какие строки должны присутствовать в результате, следует сделать это в выражении WHERE.

Код

    INNER JOIN `таблица юзеров` tblUsers 
                 ON (tblGUsers.`user_id` = tblUsers.`id` AND tblUsers.`id` = 'userOUID')

 

Автор: Gtaman 31.7.2006, 20:46
GiV, вроде работает...... Спасибо! smile 

Автор: Gtaman 31.7.2006, 21:01
GiV, блин, поспешил я радоваться...... работает только, модерирующая группа, в которой состоит чел стоит у него первой в списке групп...... 

Автор: GiV 31.7.2006, 21:08
В таком случае запрос от AntonioBanderaz должен помочь. 

Автор: Gtaman 31.7.2006, 21:52
Не помогает...... 

Автор: AntonioBanderaz 1.8.2006, 11:15
Цитата(GiV @  31.7.2006,  12:10 Найти цитируемый пост)
ON какие бы то ни было условия, накладывающие ограничения на строки в наборе результатов


Обоснуй. Я всегда думал что подключение таблиц идёт после отработки основного запроса, и запросы идёт быстрее.... тоесть в этом случае происходит сначала 
Код

SELECT 
    tblModers.*
FROM  
    `таблица модераторов` tblModers
WHERE 
    tblModers.`forum_id` = forumOUID OR tblModers.`forum_id` = 'ALL'

А потом идёт подключение первой таблицы
  `таблица членов группы` tblGUsers на совпадении условия которое в ON
и тп... Если бы разницы не было, тогда можно было просто всегда в From указывать имена таблиц через зпт. и они бы сначала все сджойнились, а потом уже шла выборка... Что случится если делать все условия в WHERE... )))) Если я не прав объясни )

Автор: GiV 1.8.2006, 11:46
Цитата(AntonioBanderaz @  1.8.2006,  11:15 Найти цитируемый пост)
тогда можно было просто всегда в From указывать имена таблиц через зпт. и они бы сначала все сджойнились, а потом уже шла выборка... 

Это уже декартово произведение.


Цитата(AntonioBanderaz @  1.8.2006,  11:15 Найти цитируемый пост)
Я всегда думал что подключение таблиц идёт после отработки основного запроса, и запросы идёт быстрее....

Вот что по тому поводу думает man (раздел по оптимизации):
Код

Выражение "A LEFT JOIN B" в MySQL реализовано следующим образом:

    * Таблица B устанавливается как зависимая от таблицы A и от всех таблиц, от которых зависит A.
    * Таблица A устанавливается как зависимая ото всех таблиц (кроме B), которые используются в условии LEFT JOIN.
    * Все условия LEFT JOIN перемещаются в предложение WHERE.
    * Выполняются все стандартные способы оптимизации соединения, за исключением того, что таблица всегда читается после всех таблиц, от которых она зависит. Если имеется циклическая зависимость, MySQL выдаст ошибку.
    * Выполняются все стандартные способы оптимизации WHERE.
    * Если в таблице A имеется строка, соответствующая выражению WHERE, но в таблице B ни одна строка не удовлетворяет условию LEFT JOIN, генерируется дополнительная строка B, в которой все значения столбцов устанавливаются в NULL.
    * Если LEFT JOIN используется для поиска тех строк, которые отсутствуют в некоторой таблице, и в предложении WHERE выполняется следующая проверка: column_name IS NULL, где column_name - столбец, который объявлен как NOT NULL, MySQL пререстанет искать строки (для отдельной комбинации ключа) после того, как найдет строку, соответствующую условию LEFT JOIN. 


INNER не делает последние два пункта.

http://mysql.com/doc/refman/4.1/en/join.html
Код

 You should generally not have any conditions in the ON part that are used to restrict which rows you want in the result set, but rather specify these conditions in the WHERE clause. There are exceptions to this rule.

Автор: Gtaman 1.8.2006, 17:18
AntonioBanderaz, 
GiV, это конечно все интересно, но моя проблема не решена..... ни один запрос не помогает.....

Автор: GiV 2.8.2006, 13:00
Код

SELECT m.*, u.*FROM `group_users` as u
LEFT JOIN moders as m ON (u.group_id=m.group_id)
WHERE u.user_id='$_SESSION[your_id]' AND (m.forum_id='$posts[fid]' OR m.forum_id='all')

Автор: AntonioBanderaz 3.8.2006, 12:23
Может у тебя связка кривая?..... 

Автор: Gtaman 3.8.2006, 18:07
Не помогает..... пишет:

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in z:\home\game.ru\www\posts.php on line 87

Если в нам вставлять, то же пишет....

Добавлено @ 18:08 
Хотя все таблицы, все поля указаны правильно!

Автор: GiV 3.8.2006, 22:18
Возьмите запросы. Вставьте их в phpMyAdmin например и посмотрите как они работают. После этого уже пишите код, а не просто вставляйте запросы в какую то часть программы, методом тыка - это не правильно.

Автор: Gtaman 3.8.2006, 23:29
Так..... в пма все работает........... Скопировал код с "Создать PHP-код", вставил в первый запрос, где определяеться модераторы, вроде все работает smile Спасибо большое! smile Если будут проблемы при работае этого запроса, сообщу. А пока - вопрос решен smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)