Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Оптимиз. MySQL-процедуры

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Для тех, кто реально в этом петрит
DeepVarvar Супермодератор
Отправлено: 11 Апреля, 2013 - 21:40:03
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




.

Так..
Чесслово, пишу процедуру, и вообще процедуру на мускуле впервые в жизни.
Ну вот не доводилось.
Написал - оказалось ничего сложного.
Однако.. есть несколько вопросов.
Сперва сам код:
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE PROCEDURE check_parent_candidate(IN main_id BIGINT(20), IN candidate_parent_id BIGINT(20), OUT STATUS TINYINT(1))
  2.  
  3.     READS SQL DATA
  4.  
  5.     BEGIN
  6.  
  7.         DECLARE i BIGINT(20);
  8.         DECLARE c BIGINT(20);
  9.         DECLARE candidate BIGINT(20);
  10.  
  11.         DECLARE children CURSOR FOR SELECT id FROM documents WHERE parent_id = main_id;
  12.  
  13.         SET STATUS = 0;
  14.         SELECT COUNT(1) INTO c FROM documents WHERE parent_id = main_id;
  15.  
  16.         IF c > 0 THEN
  17.  
  18.             SET i = 0;
  19.             OPEN children;
  20.             search : WHILE i < c DO
  21.  
  22.                 FETCH children INTO candidate;
  23.  
  24.                 IF candidate = candidate_parent_id THEN
  25.                     SET STATUS = 1;
  26.                     LEAVE search;
  27.                 END IF;
  28.  
  29.                 SET i = i + 1;
  30.  
  31.             END WHILE search;
  32.             CLOSE children;
  33.  
  34.             IF STATUS = 0 THEN
  35.  
  36.                 SET i = 0;
  37.                 OPEN children;
  38.                 subsearch : WHILE i < c DO
  39.  
  40.                 FETCH children INTO candidate;
  41.  
  42.                     CALL check_parent_candidate(candidate, candidate_parent_id, STATUS);
  43.                     IF STATUS = 1 THEN
  44.                         LEAVE subsearch;
  45.                     END IF;
  46.  
  47.                     SET i = i + 1;
  48.  
  49.                 END WHILE subsearch;
  50.                 CLOSE children;
  51.  
  52.             END IF;
  53.  
  54.         END IF;
  55.  
  56.     END$$
  57.  
  58.  
  59. DELIMITER ;

Этот кусок кода получает id редактируемого элемента и parent_id - желаемый id родителя.

Структура таблицы проста как дважда-два:

id | parent_id | name

Я проверяю, что "кандидат" на родителя не является в данный момент потомком целевого объекта,
а так же потомки потомков [потомков...[потомков...[потомков...]]] целевого объекта не являются "кандидатом" на родителя.

Теперь вопросы:

1) OUT status в аргументах процедуры - это что-то типа global $status в функции в php?
2) Когда я только объявляю курсор, запрос уже выполняется или это происходит только при OPEN курсора?
3) Второй OPEN идет за данными еще раз?
4) В первом цикле идет обход ближайших непосредственных потомков, без ухода в рекурсию, если найдено, я не пойду в рекурсию, а верну успех. Второй цикл идет уже именно по рекурсивным потомкам. Так вот, я пробовал по разному, я не знаю как, возможно есть способ ресетнуть курсор в начало и не ходить еще раз. именно по незнанию я открываю курсор еще раз. как сикануть в начало выборки чтобы не делать еще один OPEN?
5) Является ли status зарезервированным словом в MySQL?
 
 Top
caballero
Отправлено: 11 Апреля, 2013 - 22:59:29
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




пока Мелкий спит попробую ответить сам

1. нет, это именно out как в некоторый ЯП. через такой параметр можно возвращать результат назад. При вызове разумеется там должна быть переменная а не число.
счтьай что это передача по указателю или ссылке
2. происходит при FETCH
3. второй Fetch.
4. чето мудрено. резетнуть наверно вряд ли нужно просто переоткрыть
курсор - он скорее всего читается в одну сторону.
и вообще помнится ты тут агитировал за nested sets а тут какие то жуткие рекурсии на процедурах как будто это оракл а не мускул.

5) скорее всего нет - во всяком случае я такое употреблял без кавычек


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
DeepVarvar Супермодератор
Отправлено: 11 Апреля, 2013 - 23:46:35
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Появился еще один:

6) По сути выборку я делаю только внутри процедуры, ничего не возвращая наружу из этих запросов. Нужна ли тут эта READS SQL DATA?

Ответы:

1) Отлично, на это и расчитывал.
2) Ок.
3) Ок.
4) Жаль что переоткрывать - это же лишний запрос. [про nested sets и про "мудрено" ниже]
5) Ну, процедура работает, значит вроде как не зарезервированное, однако в коде это слово в нижнем регистре, а форум подсветил его в верхний, что навело на мысль.

caballero +1 в карму.

Я никогда яро не агитировал за нестед сетс.
Просто тут пару раз подряд вопросы такие всплывали, я и говорил что есть такая штука.

Насчет мудрено - это ж придумано чтобы было меньше запросов в циклах.
Насчет вообще почему не нестед сетс - это поехало еще с ранней версии - так и осталось.
Позже буду пересматривать и добавлю нестед сетс (хлебные крошки тащить точно сложно).
Однако сама процедура выполняется достаточно быстро,
потому, что для каждого вложенного уровня потомков совершает в лучшем случае один запрос,
в худшем два, для того чтобы провалиться на еще один уровень глубже.
А самих уровней вложений на сайте редко бывает более пяти.
Это максимум 10 несложных запросов в цикле за одну транзакцию.
Даже для 20 тыс записей в дереве - это фигня.
 
 Top
caballero
Отправлено: 11 Апреля, 2013 - 23:51:40
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




Цитата:
Это максимум 10 несложных запросов в цикле за одну транзакцию.
Даже для 20 тыс записей в дереве - это фигня.

так зачем вообще процедура - бегай обычными запросами или вообще в массивы выгреби и бегай там.

это не очень красиво и немного медленнее но зато намного проще.
деревья действительно редко бывают большими - в природе просто нет таких иерархий. Да и юзер не станет лазить по такому лереву
(Добавление)
а рекурcии можно избежать если не с помощью nestedsets тот с materialized path точно


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
DeepVarvar Супермодератор
Отправлено: 12 Апреля, 2013 - 00:01:38
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




caballero пишет:
это не очень красиво и немного медленнее но зато намного проще.
Таки дело принципа. Даже не остановило то, что эта процедура дергается только в момент сохранения редактируемого документа в админке.

А бегать запросами (транзакциями) на сервер тоже не хорошо - теряется время на пинание данных туда-обратно.
Это же те самые запросы в циклах на стороне пыха, о которых говорят "ффуууу!".

caballero пишет:
деревья действительно редко бывают большими
Да, но надо быть к ним готовым
Тут их уже 4 уровня, с товарами будет какраз те самые пять.
 
 Top
EuGen Администратор
Отправлено: 12 Апреля, 2013 - 00:04:24
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




В MySQL хранимые процедуры, к сожалению, оставляют желать лучшего. Поэтому почти всегда - лучше строить логику на уровне скриптов.
Ну и дерево иерархии можно реализовать двумя уровнями вложенности всегда.
По поводу 6 - READS SQL DATA означает, что процедура читает данные, собственно, но не записывает ничего (использует SELECT, но не INSERT/UPDATE/DELETE)
В MySQL это имеет характер "рекомендательной" опции, то есть реального эффекта оно не имеет никакого.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
DeepVarvar Супермодератор
Отправлено: 12 Апреля, 2013 - 00:06:41
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




EuGen пишет:
Поэтому почти всегда - лучше строить логику на уровне скриптов
Я таки посчитал, что в моем случае - лучше процедурой.

6) Да, я читал, что это не обязательная опция, но были некоторые сомнения.
 
 Top
caballero
Отправлено: 12 Апреля, 2013 - 00:06:46
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




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

но если дело принципа тоды конешно Улыбка


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
DeepVarvar Супермодератор
Отправлено: 12 Апреля, 2013 - 00:17:19
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




caballero пишет:
ну и сколько там будет категорий что их нельзя выгрести массивом
Дядь, не поверишь - все дерево.
Нет категорий.
Нет модулей (за исключение поиска, карты сайта, maybe etc..).
Есть возможная бесконечная вложенность (вкладываемость) одних документов в другие.
Есть типы (прототипы) документов, которые определяют индивидуальные информационные поля документа.
Так внутри новости может лежать товар, например, или наоборот..
Абсолютно всеравно чего захочет админ.

Так что тащить придется все дерево (возможно ~20 тыс айдишников) чтобы пробежаться по массиву.
Спасибо - неохота Закатив глазки
 
 Top
caballero
Отправлено: 12 Апреля, 2013 - 00:23:19
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




Ну так бы и сказал что хочешь свой Друпал написать.


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
DeepVarvar Супермодератор
Отправлено: 12 Апреля, 2013 - 00:32:10
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




caballero пишет:
Друпал
Почитал его API - вообще не похоже.
 
 Top
caballero
Отправлено: 12 Апреля, 2013 - 00:37:55
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




при чем тут апи?
идея друпала - все строится на таксономии
страницы формы данные и все прочее являются нодами - узлами некоего супердерева.
и админ может это все в определенных пределах перекладывать - как минимум формировать страницы из более мелких нодов.

дебильные хуки на которых строится его апи - это отдельная песня


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
DeepVarvar Супермодератор
Отправлено: 12 Апреля, 2013 - 00:43:54
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




caballero пишет:
дебильные хуки
Согласен с выражением, а по делу - проехали...
caballero пишет:
и админ может это все в определенных пределах перекладывать - как минимум формировать страницы из более мелких нодов
Ок, первое - да. Второе - нет.
Все, все - стоп. Потом, позже.
Вопрос был только о процедуре Закатив глазки
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB