![]() |
|
Модераторы: skyboy, MoLeX, Aliance, ksnk |
![]()
|
|
| imm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 27.7.2005 Репутация: нет Всего: 1 |
Доброго вам времени суток.
При проектировании сайта столкнулся с проблемой построения страницы. Долго думал и придумал, вот что: *** Модуль - ну это как у всех, спецификация и основной исполняемый класс. На выходе модуля собранный HTML (HTML я собираю с помощью Smarty). Результат выполнения модуля может иметь модули вложенные в него, т.е. после сбора HTML, остаются места для подстановки какого-либо ещё контента. Например, home_page_item это модуль который ничего не делает, а просто возвращает необходимый шаблон, в зависимости от входных параметров, а в этом шаблоне если места для подстановки шапки, левого блока, правого и тд. Более сложный пример, если у нас каталог машин и мы выбрали какую-либо для просмотра, будет отображатся более подробная инфа по указанному авто, а ниже будет выборка из поисковика, по марке выбранного авто, т.е. в модуль отображения полной инфы по авто, влаживается модуль поиска в каталоге авто с необходимыми ему параметрами. Каждое место для вложения, уникально определяется именем переменной, в которую осуществляется подстановка. Все эти имена указываются в спецификации. *** Блок - это структура, которая имеет линк на модуль, и нобор связей с другими блоками. Именно в блоке определяется что подключается и в какие подстановочные переменные собственного модуля (т.е. модуля на который у блока линк). Подключатся могут либо непосредственно модули, либо другие блоки (т.е. так же рекурсивно собираемые). Пример. home_page_item - наш модуль который ничего не делает, а просто возвращает необходимый шаблон, в зависимости от входных параметров. пусть шапка, центр, левый и правные блоки будут header, center, left, right соответственно. Далее определим блок ModelInfo который будет иметь ссылку на home_page_item, т.е. будет его выполнять, и определим связи: header <- какой нибудь модуль MegaContentItem1 left <- модуль Menu right - оставим пустой а в center подставим другой блок, там тоже будет вложение, ну например рассматриваемая нами выборка из каталога машин. Что бы не запутаться, модуль может иметь вложение, но что бы определить что именно мы вкладываем нужна оболочка в виде блока, а так же один и тот же модуль на разных страницах может содержать разные вложения и для этого достаточно определить другой блок. Физически блок это запись в таблице. Но есть ещё проблема это определение связей, так как в одно и туже подстановочную переменную модуля может быть подставленно много всякой всячены и блоки и просто обработанный HTML из какого-либо модуля, или вообще ничего, потому нужна ещё таблица для хранения этих связей. Т.е. связь определяет: какому блоку она пренадлежит, что будет дочерним (блок, модуль), в какую подстановочную переменную (модуля блока, которуму пренадлежит эта связь) будет подставлен контент полученный из дочерней структуры. Что мы имеем: - Три таблицы: Таблица параметров модуля, таблица блоков, таблица связей. - Довольно много запросов при построении страницы Зачем все это: 1. Если у нас есть большое количество подобных страниц различающиеся только наполненим центральной части, что бы создать новую нужно определить только один блок (с разметкой), сколь сложными по вложению нибыли бы другие подключаемые компоненты, они сохранятся. Т.е. что бы определить страницу, в которая бы отличалась от существующей компонетом, находящемся на вложении n понадобится создание только n новых блоков. 2. При изменении блока, изменение будет произведено, которые этот блок используют. В нашем примере с просмотром полной инфы по авто, если мы уберем связь на отображение котолога автомобилей, указанной марки, то изменения будут произведены на всех страницах автоматически, а модули останутся нетронутыми. 3. Возможнось непосредственного редактирования наполнения страниц, без изменений кода. ...и все подобное. ******************** Я это реализовал и думаю: 1. большой размер таблицы ссылок ..., но в записи все 5 полей INT... 2. много запросов ..., но исходя из личного опыта, время на запросы гораздо меньше времени построения страницы (особенно из всех этих модулей) 3. ... Короче хрнень всякая в голову лезет. Люди пожалуйста подскажите есть ли более лучшее решение поставленной задачи, с сохраненим аналогичных функциональных возможностей. Или как вообще в идеале это делают на современных CMS и подобных системах. Буду очень благодарен. |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 8 Всего: 261 |
Не совсем понял в чем ты не уверен.
Глянь вот тут, как мне показалось это то, что надо. http://forum.vingrad.ru/index.php?showtopi...nread=1&hl= |
|||
|
||||
| imm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 27.7.2005 Репутация: нет Всего: 1 |
Нет, это немножко не то. Проблема поднимаемая в указанном вами топике, это частичное получение инормации из модуля, так сказать своего рода экспорт. Моя проблема заключается совсем в другом. Мне нужен аппарат построения страницы более оптимальный нежели в среднем 1(запрос на модуль) + 1(запрос на связь) = 2 (запроса) для простейшего блок, состояшего из одного модуля и подключенного к страницы, в итоге при достаточной наполненности страницы 8-15 запросов просто на определения модулей и расстановки их на странице, а так как каждый модуль процессе выполнения будет совершать в среднем 1-3 запроса к базе данных имее 15*3=45 запросов в худшем случае.
Если использовать кеширование построенной страницы (в частности кеширование построенного блока), то можно сократить, всего до одного запроса на всю страницу, но это потребует минимум ещё одну таблицу и механизма обновления кеша страницы, использовавшей обновленный блок. Т.е. это повлечет за собой либо построения NestedSet для каждой страницы и при изменении какого либо блока, переместраивать все деревья его использующие (т.е. те где данный блок есть), либо создание дополнительной таблицы (я оговаривался вверху), куда заносятся просто метки об необходимости обнавляения соотвествующих кешев страниц и они будут обнавляены при первом заходе пользователя на соответствующую страницу. Эти оба варианта мне не нравятся, т.к. и без того три таблицы (в случае оптимизации о определенных упрощений, две) пополнятся ещё минимум одной таблицей (для кеширования). Поэтому я и спрашиваю как происходит построение страницы из блоков(модулей) в современных системах. Необходимо кординально новое решение, либо хотя бы свежие мысли. Это сообщение отредактировал(а) imm - 4.8.2006, 01:39 |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 8 Всего: 261 |
Используй столько запросов, сколько тебе надо использовать для решения задачи.
Если можно где-то сократить - сокращай, к примеру два раза посылаешь один и тот же запрос. Лучше же первый результат сохранить. Если страницы не очень часто изменяются, можно их на сервере кэшировать, глянь, в faq я писал про это. |
|||
|
||||
| imm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 27.7.2005 Репутация: нет Всего: 1 |
Оценим количество запросов к базе данных необходимых для построения страницы. В лучшем случае когда страница состоит из одного единственного блока, корневого, понадобится один запрос, типа:
SELECT b.*, i.* FROM `item` AS i, `block` AS b WHERE b.`root`=1 AND b.`item_id`=i.`item_id` AND b.`block_id`=<ID страницы>; -- Получаем корневой блок и добавляем в результат параметры модуля т.е. в лучшем случае запрос один, но в реальной жизни такого не бывает. Далее рекурсивно строим детей корневого блока, это выглядет примерно так: SELECT b.*, i.*, l.* FROM `item` AS i, `block` AS b, `link` AS l WHERE l.`parent_id`=<ID родительского блока> AND l.`node_id`=b.`block_id` AND b.`item_id`=i.`item_id` ORDER BY l.`order`; -- Получаем все блоки с параметрами соответствующих им модулей, дочерних данному блоку. Имеем по два запроса на каждую внутреннюю вершину (если добавить поле terminal, что бы не пытаться найти дочерних для листьев дерева). Если страница на содежит в себе структурированных блоков (кроме корневого), т.е. не один блок, не использует для своего построения дочерних, то мы имеем всего два запроса, если же такие блоки имеются, то неоходимо ещё по одному запросу на каждую вершину. Т.к. для пользователя будет более удобной структура, деревой которой имеет высоту большую 2, для удобства редактированния большей группы страниц одновременно, то получаем довольну внушительную цифру растущию по экспоненциальному закону от глубины дерева, количество запросов к базе данных, это притом, что для внешних вершин нужен запрос по двум таблицам, а для внутренних вершин нужен запрос по трем таблицам. Я думал над кешированием, но кешированием не откомпиленой страницы (HTML`а), так как это совсем другая история, а кеширования именно дерева зугрузки модулей, можно даже в php файлы или serialize`ованная структура, в виде какой-либо рекурсивной структуры (массивы с масивами в качестве элементов), либо в качестве одномерного массива, но с дополнитетельно добавленным параметром, определяющим уровень вложения, для построения нужной структуры. Механизм кеширования такой, когда мы изменяем какую-либо связь, мы обновляем дату построения этой связи. При построении страницы возможны следующие варианты: 1. если файл кеша не определен, то страница строется по алгоритму описанному выше и кешируется с указанием даты построения каждой связи. 2. иначе смотрим все связи кеша и составляем длинный запрос на проверку обновления какой-либо связи, от дат указанных в кеше, если такое изменение было, либо какой-то связи больше нет(в связи с её удалением), удаляем кеш и выполняем пункт 1. В противном случае строим страницу по кешу. Видим, что даже удалось обойтись теми же тремя таблицами, просто добавлением некоторых полей. С использованием кеша удалось обойтись всего одним запросом на страницу в случае корректного кеша. Но я лично плохо представляю какой длины будет строка этого запроса, если связей будет 15-20, и на сколько он будет выполняться быстро, так как логических операторов там будет в 4 раза больше чем связей ( ...(`link_id` = <ID проверяемй связи> AND `data` > <Data проверяемй связи>) OR... ), т.е. мы имеем 60-80 логических операций для каждой проверяемой связи. Так что вполне возможно, такое кеширование не сильно увеличит быстродействие, как бы совсем не наоборот. Кеширование с использованием NestedSet для каждой страницы, и в случае одновления какого либо елемента, искать деревья в этим элементом и перестраивать их, просто гиблое дело, так как перерестроения нескольких сотен деревьев в достаточно мощном проекте при любом изменении структуры блока, используемого на всех страницах (например блок seedback) будет занимать просто уйму времени и ресурсов, а это не решение. Потому я прошу, помощь с решении моей порблемы, оптимального построения страницы из структурных единиц (модулей/компонент/блоков, да как угодно). Я считаю, что моя концепция не есть лучший вариант, а так как эту проблему ставит перед собой каждый создатель системы подобной CMS и исходя из того, что таких систем огромное множество, то множно предположить, что существует огромное множество вариантов решения этой проблемы. Я буду очень благодарен за любые мысли и рекомендации по поводу решения моей проблемы. |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 8 Всего: 261 |
Если для тебя система работает, значит так и надо. А улучшения, оптимизация - это момент, который ты сам должен увидеть. Это основа работы любой CMS, видеть ее должен автор.
|
|||
|
||||
| imm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 27.7.2005 Репутация: нет Всего: 1 |
Ты хочешь сказать, что любой разработчик должен всё сам придумывать, т.е. высасывать гениальное решение из пальца??? Т.е. ты можешь сам спокойно написать пару тройку алгоритмов для поддрежки сбалансированности деревьев, нафиг нам RB, AVL и наконец знамениты B, B+ деревья, вообще не пойму зачем их кто-то придумал и ещё понапихал в разные системы, а зачем вообще нужны принципы программирования, зачем ООП, зачем MVC, ведь как у каждого получается, то так и надо... Зачем Кармен написал целую книжку по теории программирования, наверное это он так для прикола, денег захотел и всем мозги загрузил...
Как я понял для тебя программирование это, то ты сам видишь, но любая система нуждается в серёзной теоретической платформе. Я уже осознал, что PHP, это не тот язык, где вместо дикого регулярного выражения, ты напишешь симпотичный распознаватель на управлении конечного автомата. Оптимальное решение в моем понимании и в понимании PHP это кардинально разные вещи, и потому я был бы очень благодарен людям, профессионально программирующим на PHP, за помощь, в решении моей проблемы, о которой я уже неоднократно упоминал. |
|||
|
||||
| Mal Hack |
|
||||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 8 Всего: 261 |
Есть общие каноны Технологии разработки, которые надо соблюдать, к примеру глупо использовать ООП для гостевой книги, когда же ты пишешь большой проект ты сам его должен продумать от и до, всю его функциональгную схему, основываясь на общих канонах проектирования. Для разных систем важен разный принцип работы. Я свою cms сейчас пишут уже 5 раз, т.к. предыдущие разы находил пробелы в функциональной схеме, которые меня не устраивали.
Это определенные ограниченности языка. |
||||
|
|||||
| imm |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 27.7.2005 Репутация: нет Всего: 1 |
(Бьерн Страуструп "Язык программирования С++", специальное издание, стр. 765)
(Бьерн Страуструп "Язык программирования С++", специальное издание, стр. 764) А есть технологии решения конкретных задач и классов задач. А проектировка большого проекта ни коим образом не относится к постовленной мною проблеме. Я решаю задачу, но как было процетировано выше, необходимо начинать с основы заложенной другими людьми, и эта основа не язык PHP и его расширения, а решения предложенные конкретными разработчиками, в конкретных системах. А тебе пожелание, не изобретай велосипед снова и снова, и прежде чем переписывать свою CMS в 6 раз, попробуй занятся вопросом проектировки серёзно. И ещё, если звёзды зажигают, значит это кому-то нужно, если я открыл этот топик, то значит я придерживался какой-то цели. Мне надоел этот флейм, и я снова повторюсь, что буду очень благодарен за любые мысли и рекомендации по поводу решения моей проблемы. |
||||
|
|||||
| Alone |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: нет Всего: 6 |
imm, Мне кажется у вас и так все достаточно хорошо слажено.
Насчет количества запрсов к бд - я вас умоляю У меня в морде биллинга было до 1100 запросов к БД (ессесно после рефакторинга уменьшилось в десятки раз), но тем не менее, даже при таком зловещем исходе рендер страницы составлял 0.9-3.6с -------------------- |
|||
|
||||
| imm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 27.7.2005 Репутация: нет Всего: 1 |
Огромное вам спасибо на добром слове. Кстати по мере написания топика, я начинал считать свое решение не таким уж и плохим, а теперь и вообще возрадовался
Пришел к выводу, что теперь стоит вплотную занятся проблемой кеширования и оптимизации (и соответственно FrameWork писать хороший надо). P.S. Может статейку накатать, когда все продумаю по этому топику? Вопрос то довольно актуальный... |
|||
|
||||
| Alone |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: нет Всего: 6 |
Гм... по идее фреймворк сам собой напишется за это время
Если разработка на соотв. уровне -------------------- |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | PHP: Для профи | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |