Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Можно ли обойтись без вложенного SELECT?
 
 автор: Sturmvogel   (04.09.2011 в 22:23)   письмо автору
 
 

Пишу запрос
SELECT id, text FROM records WHERE author=".$this->info['id']." AND $viewer IN (can_see) ORDER BY add_date LIMIT $offset,$count


смысл в том, что в столбце can_see хранится список вида "1,2,3" id пользователей, которые могут видеть запись. Если так прямо и написать, "$viewer IN (1,2,3)", то все верно работает, если написать как выше, ничего не получается. я так понимаю, нужен вложенный SELECT запрос. Можно ли обойтись без него?

  Ответить  
 
 автор: Valick   (04.09.2011 в 22:50)   письмо автору
 
   для: Sturmvogel   (04.09.2011 в 22:23)
 

can_see - это константа?
или это поле?
или там $can_see должно быть?

  Ответить  
 
 автор: Sturmvogel   (04.09.2011 в 22:53)   письмо автору
 
   для: Valick   (04.09.2011 в 22:50)
 

can_see -- это поле в той же таблице, причем в той же строке. грубо говоря, нужно вытащить все записи какого-то пользователя (Вася), которые мог бы видеть Петя, т.е. Петя находится в списке видящих, который записан в поле can_see в формате 1,2,3 (id пользователей через запятую)

  Ответить  
 
 автор: Valick   (04.09.2011 в 23:08)   письмо автору
 
   для: Sturmvogel   (04.09.2011 в 22:53)
 

значения в поле через запятую - это прямое нарушение первого закона нормализации
при проектировании базы данных, лучше это переделать
нужно добавить таблицу связи can_see с полями id_user | id_user_see и примари кей на оба поля
___
кстати почему у вас $viewer переменная?
покажите поля таблицы

  Ответить  
 
 автор: Sturmvogel   (04.09.2011 в 23:52)   письмо автору
 
   для: Valick   (04.09.2011 в 23:08)
 

предлагаете мне создать новую таблицу can_see с полями id, record_id, user_id?

  Ответить  
 
 автор: Valick   (04.09.2011 в 23:57)   письмо автору
 
   для: Sturmvogel   (04.09.2011 в 23:52)
 

у вас Петя должен видеть все сообщения Васи или выборочно?
если все то ответил в предыдущем посте, если каждое сообщение имеет разрешение на просмотр то
record_id, user_id (id - тут не нужен, функцию первичного ключа будут выполнять оба поля - такой ключь называется составным, главное не забыть об этом сообщить базе данных)

  Ответить  
 
 автор: Sturmvogel   (04.09.2011 в 23:59)   письмо автору
 
   для: Valick   (04.09.2011 в 23:08)
 

Таблица

CREATE TABLE `records` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `author` int(11) unsigned NOT NULL,
  `text` varchar(500) NOT NULL,
  `description` text NOT NULL,
  `emotion` enum('none', 'happy', 'sad') NOT NULL DEFAULT 'none',
  `location` int(11) NOT NULL,
  `can_see` enum('all', 'friends', 'me', 'list') NOT NULL DEFAULT 'all',
  `can_see_list` varchar(255) NOT NULL,
  `cant_see` enum('none', 'all', 'list') NOT NULL DEFAULT 'none',
  `cant_see_list` varchar(255) NOT NULL,
  `count_comments` int(11) unsigned NOT NULL DEFAULT 0,
  `add_date` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;


$viewer -- это переменная, которая передается в функцию, которая формирует список записей. Переменная -- это пользователь, который просматривает страницу.

  Ответить  
 
 автор: Valick   (05.09.2011 в 00:03)   письмо автору
 
   для: Sturmvogel   (04.09.2011 в 23:59)
 

теперь яснее

  Ответить  
 
 автор: Sturmvogel   (05.09.2011 в 00:08)   письмо автору
 
   для: Valick   (05.09.2011 в 00:03)
 

А имеет ли смысл делать таблицу с полями:
record_id, user_id, privacy ('show', 'hide') -- имеется в виду поле типа ENUM

или для show и hide лучше делать разные таблицы?

  Ответить  
 
 автор: Valick   (05.09.2011 в 00:14)   письмо автору
 
   для: Sturmvogel   (05.09.2011 в 00:08)
 

сегодня уже тыква не варит)) завтра подумаю и напишу (точнее уже сегодня)) )
но по моему лучше 2 таблицы
хотя они взаимоисключающие))
если разрешено, значит не запрещено и наоборот)
___
спать, спать, спать))) а то мозг лопнет))

  Ответить  
 
 автор: Sturmvogel   (05.09.2011 в 00:32)   письмо автору
 
   для: Valick   (05.09.2011 в 00:14)
 

спасибо за помощь)))

просто чую, теперь будут дикие джоины идти в запросе))

-------

получается, придется писать что-то типа:

SELECT r.id FROM records WHERE can_see='all' AND NOT EXISTS (SELECT * FROM cant_see_list WHERE user=$visitor AND record=r.id);

???

  Ответить  
 
 автор: Sturmvogel   (06.09.2011 в 16:13)   письмо автору
 
   для: Sturmvogel   (04.09.2011 в 22:23)
 

Такой запрос будет адекватен?

SELECT id FROM records WHERE author=$author AND
can_see='all' OR
(can_see='friends' AND EXISTS (SELECT * FROM friends WHERE user_from=$author AND user_to=$viewer AND status='approved')) OR
(can_see='list' AND EXISTS (SELECT * FROM can_see_list WHERE user=$viewer AND record=id)) OR
(can_see='me' AND author=$viewer)
AND NOT EXISTS (SELECT * FROM cant_see_list WHERE user=$viewer AND record=id)
ORDER BY add_date LIMIT 10;

  Ответить  
 
 автор: cheops   (06.09.2011 в 16:21)   письмо автору
 
   для: Sturmvogel   (06.09.2011 в 16:13)
 

Если работает и скорость работы устраивает - адекватен.

  Ответить  
 
 автор: Sturmvogel   (06.09.2011 в 16:57)   письмо автору
 
   для: cheops   (06.09.2011 в 16:21)
 

ну а если нет, что и как соптимизировать можно?

  Ответить  
 
 автор: cheops   (06.09.2011 в 17:51)   письмо автору
 
   для: Sturmvogel   (06.09.2011 в 16:57)
 

Для начала можно попытаться переписать запрос с использованием объединений таблиц, посмотреть при помощи оператора EXPLAIN схему выполнения и проиндексировать соответствующие ключи. Если скорость по прежнему будет не удовлетворительной следует думать в сторону нормализации таблиц или создания кэширующей таблицы, которая бы дублировала данные из нескольких таблиц (т.е. фактически хранить копию объединенных данных).

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования