Часто задаваемые вопросы |  |
Содержание
Где взять базу к системе popoff.donetsk.ua/light?
База данных создается на страницах программиста. Страницы программиста находятся в папке public_html/prg/. Пароль для входа задается в библиотеке prg.options в файле libs/prg/prg.options.php. Скрипты для создания базы данных находятся в файлах libs/*/*.db.php.
В системе для хранения деревьев используются Nested Sets. Почему Вы выбрали именно этот способ?
Время от времени возникает вопрос о том, какой из способов
хранения деревьев лучше. Кто-то хвалит или ругает один способ, кто-то - другой.
О большинстве способов можно сказать что-то хорошее и что-то плохое.
Но здесь я не буду оценивать достоинства и недостатки способов хранения деревьев в базах данных.
Вот здесь можно найти информацию о способах хранения деревьев:
http://phpclub.ru/faq/Tree
В своей системе я выбрал Nested Sets для хранения деревьев.
Но я не буду отстаивать этот выбор, потому что я не считаю это наилучшим выбором.
Я так же не буду спешить изменить этот способ хранения деревьев на какой-либо
другой, потому что недостатки других способов хранения деревьев я тоже знаю.
Почему я выбрал именно Nested Sets? Так сложилось исторически.
В будущем, возможно, способ хранения деревьев будет задаваться в настройках.
Почему при генерации страниц выполняется так много SQL-запросов?
Действительно, в моей системе при генерации страниц может генерироваться довольно большое количество (порядка 500) sql-запросов.
Дальше я буду говорить о том, почему от большого числа запросов избавиться не просто.
Хотя я буду защищать свое «право на запросы», я все же согласен с тем, что
такое количество запросов при каждом обращении к сайту - это очень много.
Именно поэтому я ввел в систему модуль кеширования.
С его появлением много запросов выполняется только при первом обращении к
странице, а потом оно уменьшается до разумных пределов.
Время от времени возникает вопрос о том, возможно ли избавиться от большого количества запросов.
Многие говорят, что «большое количество запросов - это потому что кривые руки программиста».
На самом деле люди, которые так говорят, не понимают, что они говорят:
они привыкли писать простенькие сайтики, без поддержки мультиязычности и без
особо гибкого интерфейса - в таком случае большое количество sql-запросов
действительно говорит о кривых руках программиста.
Совсем по-другому следует рассматривать сложные системы, в которых включена
поддержка большого количества возможностей.
Можно провести исследование и выяснить, чем каждый отдельный запрос нужен для
генерации страницы и почему от него не так-то просто избавиться.
Люди, которые безоглядно борятся за уменьшение количества запросов к базе данных,
как правило не только не знают, для чего эти sql-запросы выполняются в моей
системе, но не понимают так же, для чего нужна эта борьба вообще и забывают о том, что
выиграв в одном месте - проиграешь в другом.
Порядка 90% запросов возникает из-за использованной системы поддержки мультиязычности:
все отображаемые на сайте сообщения и надписи хранятся в базе данных.
В случае, если Вы только что установили систему и у Вас полностью пустая база данных переводов,
то для каждой надписи выполняется 2 запроса, а при первом обращении - 3 запроса (1 - найти перевод на текущий язык, 2 - найти перевод на наиболее похожий язык, 3 - добавить сообщение в базу данных).
Попытаемся уменьшить это количество.
Курсивом я буду выделять то, как мне предлагали это количество уменьшить.
Начнем с малого.
Например, можно было бы уменьшить это количество до двух,
просто удалив проверку перевода на текущий язык и считать,
что текущий похож сам на себя больше чем все остальные.
Запрос для проверки перевода на наиболее похожий язык содержит в себе
сортировку по похожести языков, а для поиска
перевода на текущий язык - только поиск по уникальному ключу.
При заполненной базе данных поиск перевода выполняется по одному запросу -
поиск перевода на текущий язык.
Удалив этот запрос, при при пустой базе данных мы получили бы на 30% меньше запросов для поиска переводов.
Но при заполненной базе данных мы выполняли бы такое же
количество запросов: один для каждого сообщения, но теперь этот один запрос -
гораздо более сложный. Мы выиграли?
Хорошо, этот спсособ оптимизации - плохой. Давайте поищем в другом месте.
Например, если на странице выводятся одинаковые сообщения, то их можно было бы
кешировать и при повторном показе не выполнять sql-запрос, а доставать
сообщение из кеша. Но на страницах не так-то часто выводятся одинаковые сообщения,
гораздо чаще одинаковые сообщения выводятся между страницами, например, на
всех страницах есть название сайта. Можно было бы кешировать, например, в переменных сессии.
Ужас! Да, закешировав в переменных сессии запросы к базе данных мы действительно
уменьшили бы их количество до минимума при повторных обращениях к сайту.
Но зачем, скажите мне, делать кеширование результатов запроса средствами
php, если сама MySQL уже кеширует результаты своих запросов!
Фактически, получается, мне предлагают сделать кеш для кеша.
К тому же гораздо менее производительный, чем кеш запросов в MySQL.
Но если уж и таким способом мы ничего не выигрываем, то нужно пересмотреть вообще
весь механизм поддержки мультиязычности.
Кардинальное решение. Но здесь вопрос упирается в то, почему я выбрал именно такой способ хранения данных?
Потому что при хранении переводов в базе данных:
-
проще искать перевод на наиболее похожий язык в случае, если перевода на нужный язык нет.
-
можно автоматически добавлять новые сообщения в базу данных перевода.
Иначе я должен был бы ходить по сайту и искать, «а где это у меня там появилась новая непереведенная фараза?»
Хорошо, если на сайте всего две-три страницы и я - единственный человек, который работает над сайтом.
-
я могу предоставить администраторам привилегии на добавление новых языков, на редактирование переводов
и сделать любой удобный интерфейс для перевода сайта.
Иначе я должен был бы либо давать им ftp-аккаунты, либо закачивать вместо них
файлы переводов, либо объяснять им настройки php, либо самому настраивать,
либо объяснять им, как редактировать файлы на php,
либо каким-либо другим способом учавствовать в процессе перевода.
-
у меня одинаковым способом хранятся как переводы коротких фраз/сообщений, так и
все данные, которые зависят от языка. Эти данные есть практически в любом
модуле. В чате - названия комнат. В форуме - названия и комментарии к темам.
В модуле управления загрузкой изображений - комментарии/заголовки изображений.
В службе управления аккаунтами пользователей - названия ролей.
А в таких модулях, как служба новостей и служба управления статьями вообще
все зависит от языка.
-
текстовый файл со списком переводов одних лишь надписей для такого простенького сайта, как
popoff.donetsk.ua
весит порядка 150 КБ. Если говорить о способе хранения базы данных в виде
php-скрипта (в виде массива, в виде набора констант или любым другим способом),
то я не стану утверждать, что парсить такого размера скрипт
и искать переводы в массиве - это быстрее, чем обращаться к базе данных.
Просто мне так показалось, хотя на самом деле это может быть и не так.
-
собственно, из желания все контролировать я отказался от использования
встроенной функции
GetText().
Все переводы у меня ищутся через функцию m(), и как именно эта
функция устроена внутри - не имеет значения для остальных скриптов.
Просто изменив эту функцию можно легко изменить способ хранения сообщений.
Вопрос лишь в том, стоят ли те sql-запросы, от которых мы избавимся той
головной боли, которую мы получим взамен?
Кроме мультиязычности много sql-запросов может выполняться в следующих случаях:
-
При подсчете статистики - у меня она хранится не в одной таблице, а в нескольких.
Поэтому при каждом обращении выполняется поиск/добавление в разные таблицы.
На эти таблицы по очереди накладываются и снимаются блокировки, а наложить
блокировку и снять блокировку - это два разных sql-запроса.
О том, почему в данном случае выгоднее блокировать их разными
sql-запросами по очереди, а не сразу все, написано в документации по MySQL в
разделе «Оптимизация в MySQL - Вопросы блокировок».
Впрочем, статистика будет оптимизирована в будущих версиях.
-
Некоторые элементы страниц невыгодно кешировать, и поэтому они создают
дополнительное количество sql-запросов даже при включенном кеше.
Это в первую очередь касается тех элементов, содержимое которых меняется
при каждом обращении к сайту (например, ротаторы).
Наличие элементов этого первого типа не позволяет закешировать ВСЮ генерируемую страницу.
Во вторую очередь это касается тех элементов,
содержимое которых зависит от сессии (например, у администратора в службе новостей
могут появиться ссылки на удаление новостей - эти ссылки зависят от сессии).
Поскольку эти элементы второго типа изменяются значительно чаще, чем другие элементы страниц,
то кешировать их вместе со всеми остальными элементами не выгодно - выгоднее
кешировать отдельно часто изменяющиеся элементы и отдельно - редко изменяющиеся.
Отдельный кеш, однако, приводит к генерации отдельных sql-запросов.
-
Я с большой осторожностью отношусь к кешированию данных, которые зависят
от непроверенной информации, пришедшей от пользователей.
Первый пришедший мне в голову пример - кеширование статей.
Если я буду кешировать в зависимости от имени файла, переданного в
URL, не проверяя предварительно это имя на существование, то удаленный пользователь,
делая много запросов к разным несуществующим страницам,
может легко устроить атаку на сервер, в которой размер кеша разрастется до неимоверных размеров.
Проверка имени файла на существование требует своего sql-запроса.
То же касается и других данных.
-
Эти приведенные выше три пункта - это три места, на которые я обратил внимание,
когда создавал подсистему кеширования. Возможно, есть и другие места, на
которые я не обратил внимания.
После инсталляции системы при попытке зайти на главную страницу появляется пустая страница. | |
Если посмотреть исходный текст этой пустой страницы, то можно увидеть РНР-код.
Проблема связана с тем, что РНР-код, записанный в файлах с расширением *.html не выполняется, а отдаётся в браузер как есть. Вот возможные пути решения проблемы:
Проверьте внимательно все пути, прописанные в файлах public_html/inc-all.php и
options/addr.php. Пути в файле
inc-all.php должны указывать на каталог с файлом
addr.php.
Одна из самых распространённых ошибок - каталоги располагают не так, как они
были расположены в инсталляционном архиве и не меняют при этом пути.
Прилагающаяся инструкция по инсталляции предполагает, что структура
каталогов на диске в точности соответствует структуре каталогов в архиве.
Попробуйте в файле .htaccess, который находится в каталоге public_html поменять эту строчку (она самая первая в файле):
AddHandler application/x-httpd-php .html
на вот такую:
AddType application/x-httpd-php .html
Если Вы используете локальную версию, то проверьте, разрешена ли у Вас обработка файлов .htaccess в настройках сервера.
Для этого в файле httpd.conf нужно проверить настройку AllowOverride. Её значение для каталога, в котором установлена система должно быть
AllowOverride All. Не забывайте о том, что эта настройка может быть разная для разных каталогов, и что проверить нужно не любое одно вхождение этой настройки в файл httpd.conf, а именно то, которое отвечает за каталог с системой popoff.donetsk.ua/light.
После внесения изменений не забудьте перезапустить сервер.
Если проблема - на хостинге, то задайте этот вопрос Вашему хостеру. При этом обязательно укажите суть проблемы, что в файлах с расширением *.html РНР-код не выполняется, а выдаётся в браузер в исходном виде. Возможно, на Вашем хостинге нужны какие-то особые настройки - такое бывает довольно часто.
Перед тем, как задавать вопрос хостеру - попробуйте внести описанное в первом пункте
изменение в файл .htaccess - поменять AddHandler на
AddType.
Изучите FAQ Вашего хостера. Проблема, с которой Вы столкнулись - часто встречаемая и, возможно, на сайте Вашего хостера уже есть ответ на этот вопрос.
Если ничего не помогло, то всё, что я могу сделать - это попросить Вас разобраться с тем, почему у Вас возникает этот эффект и выложить в комментарии к этой странице описание сути проблемы и способа решения проблемы в Вашем конкретном случае.
Смотрите также | |
Многоязычность в движке для портала
Некоторые особенности устройства подсистемы поддержки многоязычности (вопрос в форуме)
Выбираем лучший инструмент: Объектно-ориентированное и процедурное программирование в PHP
http://phpclub.ru/detail/article/oop-vs-proc
Последняя модификация: 16.06.08 01:19 q Не проходите мимо! Оставьте Ваш комментарий в форуме! >>> Цитирование материалов моего сайта приветствуется! при условии видимой действующей! гиперссылки на мой сайт. [Ссылки] Если Вы нашли опечатку на этой странице, пожалуйста, выделите ее мышью и нажмите Ctrl+Enter. Сделаем язык чище! (c) Yuri Popoff, 2004 - 2008, popoff.donetsk.ua, style.donetsk.ua |
|