Покинул форум
Сообщений всего: 310
Дата рег-ции: Дек. 2010
Помог: 0 раз(а)
Доброго времени суток!
Как лучше организовывать ЧПУ в движке с большой кучей контента и с учетом достаточно высокой посещаемости?
Сейчас там нет единой точки входа, но это я поправляю. Все будет через index.php
Если делать без правил в htaccess, и с REQUEST_URI, то как лучше запрос делать на выборку из БД?
Типа WHERE url = $url или LIKE использовать?
Может есть у кого какой-то класс не сложный или функция для роутинга?
Viper
Отправлено: 26 Октября, 2011 - 07:33:33
Активный участник
Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007 Откуда: Симферополь
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Вот ссылка про ЧПУ http://forum.php.su/topic.php?fo...mp;v=#1313051903
На счет БД.
Если есть возможность:
Сделайте дополнительное поле crs тип int()
И при внесении/изменении через триггеры или сам запрос в это поле вносите CRC32(`URL`) и сделайте по нему индекс
Тогда запрос будет SELECT .... WHERE crs=CRC32(`URL`) AND url=`URL`;
Если нет такой возможности:
Тогда SELECT .... WHERE url=`URL`;
На счет индекса по нему, тут сложно, сделайте, но он может оказаться очень большим если размер не критичен, тогда делайте
dropoff
Отправлено: 26 Октября, 2011 - 18:55:52
Посетитель
Покинул форум
Сообщений всего: 310
Дата рег-ции: Дек. 2010
Помог: 0 раз(а)
tuareg, спасибо.
Поле crs сделать, в принципе, можно.
А большая вероятность того, что данные будут не верны, чтобы еще и контрольные суммы сверять?
tuareg
Отправлено: 26 Октября, 2011 - 20:15:18
Участник
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Суть не в том что данные будут не верны, а в том что Вы сделаете индекс по полю типа int. Он занимает гораздо меньше места
dropoff
Отправлено: 26 Октября, 2011 - 21:15:17
Посетитель
Покинул форум
Сообщений всего: 310
Дата рег-ции: Дек. 2010
Помог: 0 раз(а)
Все. Понял наконец!
Хорошо.
Тогда такой вопрос.
А если сделать отдельную таблицу для УРЛов всех типов данных.
Например таблице page_url такой структуры
id - ну тут понятно
content - тип контента. например: news, articles, producs...
alias - УРЛ. (обзову так, по совету Viper ;)
crs - CRC32()
в таблице, например news, заносить в поле alias - ID соответствующее в таблице page_url
а потом в запросе JOIN'ить таблицу page_url.
Я это к чему. Тогда можно будет реализовать еще и редактирование УРЛ'ов из админки.
Сильно такой подходит увеличит нагрузку?
С CRC32 смущает вот что. Если, к примеру, чел захочет сменить УРЛ через PMA. Тогда уже он не будет совпадать с контрольной суммой. А вероятность того, что кто-то будет это делать очень высока.
tuareg
Отправлено: 27 Октября, 2011 - 08:26:37
Участник
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
dropoff --->> Если, к примеру, чел захочет сменить УРЛ через PMA.
Вот я не понял??? Поподробнее объясните пожалуйста с примером.
Если делать через 2 триггера(1 первый триггер сработает после вставки, а второй после UPDATE) то как бы кто-то не изменял URL он все равно пересчитает CRS.
На счет таблицы (вот тут просто мое мнение)
Я бы сделал также, но только добавил бы поле таблица( в вашем случае если каждому типу поля content соответствет одна таблица тогда не надо), где указывал бы к какой таблице относится данный URL. И в процедуре MySQL простым запросом искал есть ли такой URL и если есть выводил id и таблица и если есть вторым запросом выводил данные. В принципе можно и без процедуры, а 2 запроса.
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Насчет РМА--->>> триггеры
Зачем изменять что-то через PhpMyAdmin если есть админка?
Плюс если будет какая-то дополнительная логика например
создаю новую текстовую страницу заполнил все поля
если мы берем 2 таблицы
в первой--->url и.д
во второй ----> сам контент
Тогда сохранение будет выглядеть так: выполнить запрос на вставку в таблицу с url---->>>Потом узнать id последней записи в таблицу с url------> выполнить запрос в таблицу с контентом
(Тут я не указал еще необходимость на проверку уникальности URL.)
Каким образом это просто сделать через РМА я не знаю.
dropoff
Отправлено: 27 Октября, 2011 - 19:20:24
Посетитель
Покинул форум
Сообщений всего: 310
Дата рег-ции: Дек. 2010
Помог: 0 раз(а)
Цитата:
Зачем изменять что-то через PhpMyAdmin если есть админка?
ну мало ли кому, что в голову взбредет. Двиг будет доступен для скачивания. И не факт, что кто-то не полезет менять УРЛы в phpmyadmin или еще что-то...
При добавлении новости в c_page_url пишем content - news content_id - id новости url пишем tittle через функцию транслита, перед эти проверяя на уже добавленные. (если уже есть такой url, то добавляем ему +1 в конце)
Т.е. таблица c_news по факту не содержит в себе никаких url'ов
К примеру в запросе у нас
site.ru/pervaya-novost
$getUrl = SELECT * FROM c_page_url WHERE content = 'news' AND url = 'pervaya-novost' - первый запрос
далее дергаем новость
$getnews = SELECT * FROM c_news WHERE id = $getUrl['content_id'] - второй запрос
Я правильно понял?
Тут главное, чтобы запрос быстро выполнялся, как вы понимаете.
На выборку одной новости это не критично. А вот, если тянуть список новостей по категориям + постраничность...
tuareg
Отправлено: 28 Октября, 2011 - 02:15:59
Участник
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
На счет PMA. Вот есть страниц 500 к примеру. Я начинаю править url страницы.
Как вы думаете есть шанс, что я исправлю так что у меня получится что 2 страницы с одинаковым URL?
И как тогда будет работать движок?
Насчет всех запросов тут напрашиваются процедуры MySQL.
Они по-моему начиная с версии MySQL 5.0 (тут не уверен) не требуют ни каких SUPER прав. Они нормально будут работать.
На счет запросов
`id` int(11)UNSIGNEDNOTNULL,# Сделав поле беззнаковым мы #увеличим его значение приблизительно 2 раза
#title здесь не нужен он нужен в таблице url
`text` text NOTNULL,
`date_added` date NOTNULL,
UNIQUEKEY`id`(`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Сделав таблицу "фиксированной" (не содержащей поля типа varchar, text, blob) мы чуть выиграем в скорости ее работы.
Поле `hide`---> наверняка будет возможность скрыть какую-то страницу от пользователей?
Тут тоже я всегда перечисляю какие поля мне нужны в запросе. Т.е не * ,а `id`,`url` и т.д
У нас нет индексов кроме PRIMARY KEY. Пока приложение толком не готово я обычно их не ставлю.
Да и еще сразу пока не забыл лучше,если у нас не будет отрицательных числовых значений, сделать числовые поля беззнаковыми (unsigned)
Вот мы подготовились и сделали таблицы
Теперь запрос на сохранение/редактирование будет состоять из 3 этапов
1 этап:
* если новая новость -->0, если редактируем id
** находим контрольную сумму. Если будут триггера тогда это поле вставлять не надо
*** это тип(таблица) в которой хранится контент и т.д
3 этап:
$id=>>> Если делали новую страницу находим последний сгенерированный id, редактирование id нам известен
P.S Сейчас еще рано ставить индексы. Любая здоровая критика приветствуется
P.S.S Это всего лишь пример, нет проверок и экранирования, но это не та тема
Покинул форум
Сообщений всего: 310
Дата рег-ции: Дек. 2010
Помог: 0 раз(а)
Цитата:
На счет PMA. Вот есть страниц 500 к примеру. Я начинаю править url страницы.
Как вы думаете есть шанс, что я исправлю так что у меня получится что 2 страницы с одинаковым URL?
И как тогда будет работать движок?
Ну, я имел ввиду не все URL'ы править ) Просто бывают ситуации когда человек и там умудриться полазить...) Проконтролировать, то это не возможно. Соответственно, нужно предусмотреть и такой вариант.
Цитата:
А откуда Вы будете знать что это news?
Вот тут я конечно упустил один момент и не поделился им.
Типы данных определять по "ключу" в ссылке.
Пример: site.ru/news/category-name/news- name
REQUEST_URI вернет массив (после обработки конечно же)
вида
смотрим, что пришло из $url, и если есть такой мод - грузим его. Новости и статьи как раз и будут в виде модулей
вернет категорию новостей или статей. в зависимости от того, что у нас в $url[0]
SELECT * FROM c_page_url WHERE content = $url[0] AND url = $url[1]
вернет новость или статью
SELECT * FROM c_page_url WHERE content = $url[0] AND url = $url[2]
*/
}
else//если мода нет, то это товар. т.е. ссылка вида site.ru/products-cat/product-name
include'products.php';
/*
вернет категорию
SELECT * FROM c_page_url WHERE content = 'products' AND url = $url[0]
вернет товар
SELECT * FROM c_page_url WHERE content = 'products' AND url = $url[1]
*/
}
Примерно так. Так как сейчас модульная система работает по похожему сценарию, только там не include, а подгружается функция.
И типы контента (новости, статьи, страницы) - уже все реализованы... правда пока как отдельные сущности, а не модули.
Вот тут я как раз и застрял.
В таком случае получается, что название категории новостей не может совпадать с названием новости и т.д... Так как все URL'ы записаны в одной таблице.
В таблице c_page_url нужны только URL'ы (ну там id контента еще и определяющую контента (news,articles...)). В противном случае нужно будет весь двиг переделывать)
Если вывод контента делать через два запроса, то тогда получится их много.
Вывод 5 последних новостей - 2 запроса
Вывод 5 последних статей - 2 запроса
Вывод 5 рекомендуемых товаров - 2 запроса
Вывод 5 новых товаров - 2 запроса
Вывод 5 самых продаваемых товаров - 2 запроса
Вывод информационных страниц - 2 запроса
+ запросы на определения юзера
+ запросы корзины
+ запрос на модули (включение и настройки)
+ запросы всяких налогов, скидок и т.д..
В реале их сейчас минимум 25. А если еще с УРЛ'а ми по два запроса, то очень много выходит((
Может тут проще кэшировать (в каком-то удобном виде в файл) запрос на URL, а потом из него дергать, что нужно?
Хотя, если контента будет несколько сот тысяч, то файл будет не маленький в объеме.
tuareg
Отправлено: 28 Октября, 2011 - 13:07:49
Участник
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Цитата:
Просто бывают ситуации когда человек и там умудриться полазить...) Проконтролировать, то это не возможно. Соответственно, нужно предусмотреть и такой вариант.
Триггеры, и хоть как правьте он пересчитает эту сумму. dropoff Давайте определимся. Что мы хотим?
Хотим ли мы написать новое?
Хотим ли мы исправить то что есть?
И от этого двигаться
Цитата:
Если вывод контента делать через два запроса, то тогда получится их много.
Вывод 5 последних новостей - 2 запроса
Вывод 5 последних статей - 2 запроса
Вывод 5 рекомендуемых товаров - 2 запроса
Вывод 5 новых товаров - 2 запроса
Вывод 5 самых продаваемых товаров - 2 запроса
Вывод информационных страниц - 2 запроса
+ запросы на определения юзера
+ запросы корзины
+ запрос на модули (включение и настройки)
+ запросы всяких налогов, скидок и т.д..
В реале их сейчас минимум 25
Зачем тут везде по 2 запроса? Некоторые можно вообще объединить в 1 Например
Вывод 5 рекомендуемых товаров - 2 запроса
Вывод 5 новых товаров - 2 запроса
Вывод 5 самых продаваемых товаров - 2 запроса
Это скорее всего можно через 1 запрос вывести.
Потом поймите правильно, простой запрос он на то и простой, что выполняется быстро+есть шанс что он попадет в КЭШ MySQL, тогда он вообще второй раз выполняться не будет.
dropoff
Отправлено: 28 Октября, 2011 - 19:01:39
Посетитель
Покинул форум
Сообщений всего: 310
Дата рег-ции: Дек. 2010
Помог: 0 раз(а)
Цитата:
Давайте определимся. Что мы хотим?
Исправить то что есть. Новое делать - очень много переписывать.
Некоторые можно вообще объединить в 1 Например
Вывод 5 рекомендуемых товаров - 2 запроса
Вывод 5 новых товаров - 2 запроса
Вывод 5 самых продаваемых товаров - 2 запроса
Это скорее всего можно через 1 запрос вывести.
Все одним? Вы уж простите, у меня с запросами тугова-то пока)
Цитата:
Потом поймите правильно, простой запрос он на то и простой, что выполняется быстро+есть шанс что он попадет в КЭШ MySQL, тогда он вообще второй раз выполняться не будет.
tuareg
Отправлено: 29 Октября, 2011 - 08:10:48
Участник
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Я же Вам в первом посте дал ссылку там все описано про ЧПУ.
Я не так сильно ориентируюсь в PHP, чтобы Вам в этом помочь. На счет запросов MySQL выкладывайте структуру Таблиц и что надо сделать помогу.
Мелкий
Отправлено: 29 Октября, 2011 - 09:33:23
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
tuareg пишет:
Потом поймите правильно, простой запрос он на то и простой, что выполняется быстро+есть шанс что он попадет в КЭШ MySQL, тогда он вообще второй раз выполняться не будет.
Таки в кэш попадают все, кто в него умещаются. Будь хоть чудовищно сложный запрос на десяток таблиц, но возвращающий пару строк - он попадёт в кэш.
dropoff пишет:
В реале их сейчас минимум 25. А если еще с УРЛ'а ми по два запроса, то очень много выходит((
Кэшируйте запросы. На вас никто не обидится, если блок новостей опоздает обновиться на пару минут.
+ тут действительно не нужно столько запросов.
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.