powered by simpleCommunicator - 2.0.57     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Терзают сомнения
11 сообщений из 11, страница 1 из 1
Терзают сомнения
    #32261699
arm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пишу форум на perl+Mysql. Есть сомнения, что организация форума строиться не рационально, что вдальнейшем может выйти боком. Хочется выянить это на стадии разработки и перекроить если нужно.
Каким-то корявым он мне кажется :-)). Буду благодарен совету или комментарям.
Форум пишется как часть движка сайта.
Таблицы юзеров, сессии, права доступа и тп уже есть в движке.
по всей видимости форум должен состоять минимум из 3х таблиц:
таб. разделов (форумов)-forum_forum, таб. топиков-forum_topic и таб. постов-forum_post.
при просмотре топика, вместе с постом должна выводиться инфа о юзере и кол-ве его постов.
отталкиваясь от этого была написана предварительная версия форума.

Вот пример запроса для просмотра топика (users-табл. юзеров, forum_post.msg - сообщение юзера)
кол-во постов каждого юзера определяется аггрег ф-цией COUNT, для чего таб. forum_post исполь. дважды
($p_FORMDATA->{id} - хранит ид топика)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
    SELECT 
    		forum_post.id AS post_id,
    		forum_post.date AS date,
    		forum_post.user_id AS user_id,
    		users.login AS user_login,
    		users.email AS user_email,
    		users.image_id AS user_photo,
    		users.home_page_url AS user_homepage,
    		forum_post.msg AS msg,
    		COUNT(fp.id) AS postings_count,
    		forum_topic.name as topic_name
    FROM	forum_post,
    		users,
    		forum_post AS fp,
    		forum_topic
    WHERE	forum_post.topic_id=$p_FORMDATA->{id}
    		AND (forum_post.user_id=users.id)
    		AND (fp.user_id=users.id)
    		AND forum_topic.id=$p_FORMDATA->{id}
    GROUP BY forum_post.id
    ORDER BY post_id


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

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

Далее возникло требование: вести счетчик уникальных просмотров топиков и показывать в списке форумов логин и ид юзера, сделавщего последний пост. Т.образом, необходимость извлечения инфы о уникальных хитах, кол-ве постов и последнем юзере побудили к созданию еще одной таблицы - forum_info.

Таблица forum_info со столбцом-sid, уникальным по сочетанию ид_сессии юзера и ид_топика.
поле sid обеспечивает уникальность хитов - сюда пишется CONCAT(sid,topic_id) для уникальности хитов, и CONCAT(sid,topic_id,post_id) когда выполняется пост для неуникальности счетчика постов.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE TABLE forum_info (
  sid char( 32 ) NOT NULL default '0',
  time timestamp( 14 ) NOT NULL,
  post int( 12 ) unsigned default '0',	 /* счетчик постов */ 
  post_id int( 12 ) unsigned default NULL,
  user_id int( 12 ) unsigned default '0',
  user_login char( 30 ) default NULL,
  top_post tinyint( 4 ) unsigned NOT NULL default '0',
  hit int( 12 ) unsigned default '0',		 /* счетчик просмотров */ 
  topic_id int( 12 ) unsigned default '0',
  forum_id int( 12 ) unsigned NOT NULL default '0',
  UNIQUE KEY sid (sid)
) TYPE=MyISAM;


При каждом просмотре топика юзером делается INSERT IGNORE с полем hit=1 в эту табл. -> сумма всех хитов в этой табл. с указанным ид топика и есть счетчик для данного топика.
При каждом посте делается аналогично с post=1, и записывается ид и логин изера сделавшего пост (он будет юзером сделавшим последний пост).

тогда список разделов (форумов) вытягивается запросом:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  SELECT 
    		forum_forum.id AS forum_id,
    		forum_forum.name AS forum_name,
    		SUM(forum_info.top_post) AS topics_count,
    		MAX(CONCAT(forum_info.sid, "###" ,'mysor', "###" ,forum_info.user_id, "###" ,
forum_info.user_login, "###" )) AS last_post_info,
    		SUM(forum_info.post) AS reply_count,
    		SUM(forum_info.hit) AS forum_hits
  FROM	forum_forum
    		LEFT JOIN forum_info ON (forum_info.forum_id=forum_forum.id)
  GROUP BY forum_id
  ORDER BY forum_id ASC

(last_post_info - парзится в скрипте).

В итоге использование табл. forum_info, по моему разумению, должно избавить запрос от нескольких сложных join'oв и суммирований, манипулирующих с 3-мя таблицами: users,forum_post, инфой о хитах(гдебы она не была).

Но с другой стороны, - возникают некоторые трудности. Во-первых, при удалении топиков, надо всед за табл. forum_topic & forum_post удалять и инфу из forum_info. Это еще ладно, но при удалении последнего
поста в топике - в forum_info надо менять инфу о юзере сделавшем последниий пост. Также требуется особая забота о логической целостности (согласованности) данных в forum_info с ост. форумом. Для чего я написал несколько скриптов, которые проверяют форум и суммируют (сжимают) инфу в forum_info.
Не криво ли это?
Не будут ли действия админа (несколько делейтов) вызывать лишние блокировки других запросов?
...
Рейтинг: 0 / 0
Терзают сомнения
    #32262591
arm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
???
...
Рейтинг: 0 / 0
Терзают сомнения
    #32262640
Фотография fedd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я бы ответит с удовольствием, но времени не хватает...

на первый взгляд - освобождайся от конкатов... храни "хиты" в спец. поле таблицы "топик"
...
Рейтинг: 0 / 0
Терзают сомнения
    #32262647
Фотография fedd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
на всякий случай, вдруг ты не знаешь, уникальный ключ может состоять из нескольких полей...

я невнимательно читал, но мне показалось, что ты не знаешь
...
Рейтинг: 0 / 0
Терзают сомнения
    #32262699
arm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
к сож. пост получился cлижком громоздкий, тк хотелось подробнее раскрыть проблему.

насчет уникального ключа из нескольких полей - я знаком с этим. конкат использую тк посчеты хитов и топиков ведуться в одной таблице (forum_info) и если уникальность (сесион_ид,топик_ид) необходима для хита, то это недопустимо для постинга юзера, который в одну сессию можег оставить в одном топик енесколько постов. вот почему пока испол. уникал. поле sid которое для хитов формируется как CONCAT(sid,topic_id,ФИКСИРОВАННЫЙ_недопустимый_номер_поста), а для постов как CONCAT(sid,topic_id,post_id). хотя тут возможны варианты.

что касается хранения инфы о хитак в табл. forum_topic здесь видится 2 момента:
1 - нехочется делать апдейт таблицы при каждом просмотре топика. мне кажется инсерт в forum_info будет быстрее и менее чувствительно в плане одновременного доступа к таблице.
2 - теряется уникальность по сессии. (как например в данном форуме) один узер может многократно за сеанс нкликать кол-во хитов.
...
Рейтинг: 0 / 0
Терзают сомнения
    #32262766
Фотография fedd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
совет.

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

совет 2.

хит - это новая сущность. для нее сделай отдельную таблицу

хит по топику
====
ид хит (bigint auto_increment)
ид юзера
время
ид топика

если нужно считать хиты по постам, то еще одну таблицу

хит по посту
====
ид хит (bigint auto_increment)
ид юзера
время
ид топика
ид поста

сорьки, никак не въеду в идею со сложными sid в таблице forum_info. не совсем обеспечен временем. давай подождем кого-нибудь еще.

как мнемоническое правило типа "под вистуза - с туза" - лучший айдишник - это бигинт автоинкремент

конструкция MAX(CONCAT forum_info.sid,"###",'mysor',"###",forum_info.user_id,"###", forum_info.user_login,"###")) AS last_post_info будет работать 30 лет и три года
...
Рейтинг: 0 / 0
Терзают сомнения
    #32262829
arm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
к совету 1:
клади юзер и время последнего поста в спец поля таблицу топика - избавит от необходимости решения распространенной задачи "найти максимум из одной таблицы для каждой записи в другой".
это значит, что При добалении поста нужен еще один апдейт. А при удалении поста юзера, если он последний в топике, надо определить последнего юзера и снова сделать апдейт в табл. топиков. После чего удалить строку из табл. хиты_постингов, чтобы уменьшить счетчик постов юзера на 1. Я пытался избежать лишних апдейтов - щас вижу не уйти от этого. еще важно проверять согласованность данных о кол-ве постов и посл. юзере хранящемся в табл. топика и хитов_постинга и их реальнами значениями в табл. forum_post.

к совету 2:
хит - это новая сущность. для нее сделай отдельную таблицу

хит по топику
====
ид хит (bigint auto_increment)
ид юзера
время
ид топика

если нужно считать хиты по постам, то еще одну таблицу

хит по посту
====
ид хит (bigint auto_increment)
ид юзера
время
ид топика
ид поста

одна из причин почему я полез в эти дебри (использование таблицы forum_info в стиле все-в_одном) явл то, что мне не хотелось при отображении списка форумов или топиков делать несколько сложных join'ов в селектах. а как же иначе получить таблицу инфы:
Код: plaintext
1.
2.
3.
4.
5.
   имя_форума |
   кол-во_топиков | 
   суммарное_колво_постов |
   суммарное_кол-во_хитов |
   последний_юзер (пост)


причем обрати внимание: инфа о последнем юзере Форума, требует нахождения последнего из всех топиков, принадлежащих данному форуму.
...
Рейтинг: 0 / 0
Терзают сомнения
    #32263347
Фотография fedd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
к ответу на совет 1

абдейт неиндексированного поля происходит очень быстро, в отличие от любого инсерта. я бы инсертов больше избегал.

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

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

что-то никто не подключается. может я чушь гоню, а меня никто не поправит...
...
Рейтинг: 0 / 0
Терзают сомнения
    #32263439
arm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
достигнешь быстродействия, приемлемого для веба, засчет того, что будет отображаться немного не та правда, которую ты хотел бы: если пост удален, все равно он был последним, это тоже правда, пусть отображается.

:-) принципе такой филлосовский подход, вполне приемлим, если даст выигрыш в быстродействии. Однако представь ситуацию: мы просматриваем профиль юзера, счетчик его постов - 5. хотим почитать что он пишет - а скрипт возвращ. что в базе его постов нет. у посетителя сайта сложится недоверие к инфе возвращаемой скриптами сайта.
так же характерно, что удаляются обычто 'левые' посты, например, (пардон) возмет кто-нить ник=Конская_залупа и накидает постов. админ их удалит, но в списке топиков, будет красоваться ник злоумышленника.
...
Рейтинг: 0 / 0
Терзают сомнения
    #32263508
arm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кол-во апдейтов-интсертов-селеков (с учетом других отличных от форума обращений к базе) хочется уложить в рамки хостинга приблизительно от10$ при возможно 5-10 пользователей одновременно нах-ся на сайте.
...
Рейтинг: 0 / 0
Терзают сомнения
    #32264117
arm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а в ответ - тишина. неужели ни у кого нет мнений?
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Терзают сомнения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]