2013-05-01 2 views
2

Хорошо, поэтому мне нравится создавать программное обеспечение для форумов с PHP и MySQL, хотя есть одна вещь, которая меня всегда беспокоила, и только одна вещь;Создание программного обеспечения для форума - поиск лучшего способа сделать 1 вещь

Главная страница форумов, на которой вы просматриваете список форумов. Каждый форум показывает название форума, количество сообщений, сделанных на этом форуме, количество обсуждений на этом форуме и последний плакат на форуме. Возникает проблема, получая все эти данные, когда все эти вещи хранятся в разных таблицах. Это не большая проблема, чтобы ПОЛУЧИТЬ это, а не проблема, но сделать это ЭФФЕКТИВНО - это то, что мне нужно.

Мой нынешний подход - это; Храните текущее количество сообщений, обсуждений и последнего плаката статически в самой таблице форума вместо того, чтобы выходить и захватывать данные из разных таблиц - «сообщения», «обсуждения», «форумы» и т. Д. Затем, когда сообщения пользователей, он обновляет таблицу «форумов», увеличивая количество сообщений на 1 и обновляя последний плакат, а также увеличивая количество обсуждений на 1, если они приступают к новому обсуждению. По какой-то причине это кажется мне неэффективным и грязным, но, возможно, это только я.

И вот еще один подход, который, я боюсь, был бы ужасно неэффективным; Фактически выходить на каждый стол - «сообщения», «обсуждения», «форумы» - и захватывать данные. Проблема в том, что на одной странице могут быть сотни форумов ... И мне нужно будет использовать оператор COUNT для получения количества сообщений или обсуждений, то есть мне придется использовать подзапросы - не говоря уже о третий подзапрос, чтобы получить последний плакат. Это, как говорится ... Запрос будет что-то вроде этого псевдо-коды, как-вещей:

SELECT foruminfo, (
    SELECT COUNT(id) 
    FROM posts 
    WHERE forumId = someid 
), (
    SELECT COUNT(id) 
    FROM discussions 
    WHERE forumId = someid 
), (
    SELECT postinfo 
    FROM posts 
    WHERE forumId = someid 
    ORDER BY postdate 
    DESC LIMIT 1 
) 
FROM forums 
ORDER BY position DESC; 

Поэтому в основном эти подзапросы можно запускать сотни раз, если у меня есть сотни форумов быть перечислены. И с сотнями пользователей, просматривающих страницу каждую секунду, не помешало бы этому немного напрячься? Я не совсем уверен, что подзапросы вызывают ту же нагрузку, что и обычные запросы, или нет, но если они это сделают, то, похоже, это будет ужасно неэффективно.

Любые идеи? :(

ответ

2

Я построил большие системы масштаба форума прежде, и ключ, чтобы сделать его производительным является де-нормализуют ничего и все, что вы можете.

Вы не можете реально использовать JOIN на самом деле популярных страниц. Вы должно содержать количество запросов, которые вы выдаете, до абсолютного минимума. Никогда не следует использовать подвыборки. Всегда убедитесь, что ваши индексы покрывают ваши конкретные варианты использования и не более. Запрос, который занимает больше 1-5 мс для запуска, вероятно, тоже слишком медленный, чтобы работать на сайте, который работает в масштабе. Когда из-за сильной нагрузки вещи внезапно занимают в десять раз больше времени, чтобы запустить запрос 15 мс, он будет наносить ущерб 150 мс или более, в то время как ваши оптимизированные запросы 1 мс будут принимать приемлемые 10 мс. они должны быть 0.00s все время, и возможно t o сделайте это.

Помните, что в любое время, когда вы выполняете запрос и ожидаете ответа, вы не можете ничего сделать. Если вы немного небрежны, у вас будут запросы быстрее, чем вы можете их обработать, и вся система будет прятаться.

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

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

SELECT id, username, user_avatar, post_title, post_count, post_time FROM posts 
    WHERE forum_id=? 
    ORDER BY id DESC 

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

В случае, с которым я работал, это было обязательным требованием для публикации вещей в будущем, а также в прошлом, поэтому мне пришлось создать определенный «ключ сортировки» независимо от ID, например, ваш position , Если это не так, для вас, просто использовать первичный ключ id для заказа, что-то вроде этого:

INDEX post_order (forum_id, id) 

Использование SUM или COUNT полностью из вопроса. Вам нужны столбцы счетчика-кэша. Это то, что позволяет сэкономить количество сообщений на конкретном форуме. Да, они будут выходить из строя время от времени, как любые ненормированные данные, поэтому вам нужно будет добавить инструменты, чтобы держать их под контролем, чтобы полностью восстановить их, если это необходимо. Обычно вы можете сделать это как cron-задание, которое выполняется один раз в день, чтобы устранить любую незначительную коррупцию, которая могла произойти. В большинстве случаев, если вы правильно выполняете свою реализацию, они будут полностью синхронизированы.

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

Кроме того, кешируйте все, что вы можете уйти, чем-то вроде Memcached, если это вариант. Например, список друзей пользователя не изменится, если друг не добавлен или удален, поэтому вам не нужно постоянно выбирать этот список из базы данных. Самый быстрый запрос к базе данных - это тот, который вы никогда не делаете, не так ли?

Чтобы сделать это правильно, вам нужно знать расположение каждой страницы и информацию о ней. Страницы, которые не слишком популярны, нуждаются в меньшей оптимизации, но что-либо в главной линии огня должно быть тщательно изучено. Как и многие вещи, вероятно, существует правило 80/20, где 80% вашего трафика попадает только на 20% от вашей кодовой базы. Вот где вы хотите быть в лучшем состоянии.