|
Терзают сомнения
|
|||
---|---|---|---|
#18+
Пишу форум на 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.
соответств. запрос для списка форумов, возвращ. кол-ва топиков и постов группированных по форумам, тоже обращ. а при удалении топика администратором сначала удаляется запись из табл. топиков, затем удаляются все относящиеся к нему посты из таблицы постов. Вот тут возник первый вопрос: Может лучше не удалять записи, а помечать их как удаленные с помощью поля-признака удаления, однако это должно отриц. сказаться на эффективности использования индексов. Далее возникло требование: вести счетчик уникальных просмотров топиков и показывать в списке форумов логин и ид юзера, сделавщего последний пост. Т.образом, необходимость извлечения инфы о уникальных хитах, кол-ве постов и последнем юзере побудили к созданию еще одной таблицы - 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.
При каждом просмотре топика юзером делается INSERT IGNORE с полем hit=1 в эту табл. -> сумма всех хитов в этой табл. с указанным ид топика и есть счетчик для данного топика. При каждом посте делается аналогично с post=1, и записывается ид и логин изера сделавшего пост (он будет юзером сделавшим последний пост). тогда список разделов (форумов) вытягивается запросом: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
(last_post_info - парзится в скрипте). В итоге использование табл. forum_info, по моему разумению, должно избавить запрос от нескольких сложных join'oв и суммирований, манипулирующих с 3-мя таблицами: users,forum_post, инфой о хитах(гдебы она не была). Но с другой стороны, - возникают некоторые трудности. Во-первых, при удалении топиков, надо всед за табл. forum_topic & forum_post удалять и инфу из forum_info. Это еще ладно, но при удалении последнего поста в топике - в forum_info надо менять инфу о юзере сделавшем последниий пост. Также требуется особая забота о логической целостности (согласованности) данных в forum_info с ост. форумом. Для чего я написал несколько скриптов, которые проверяют форум и суммируют (сжимают) инфу в forum_info. Не криво ли это? Не будут ли действия админа (несколько делейтов) вызывать лишние блокировки других запросов? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.09.2003, 20:42 |
|
Терзают сомнения
|
|||
---|---|---|---|
#18+
я бы ответит с удовольствием, но времени не хватает... на первый взгляд - освобождайся от конкатов... храни "хиты" в спец. поле таблицы "топик" ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2003, 15:55 |
|
Терзают сомнения
|
|||
---|---|---|---|
#18+
на всякий случай, вдруг ты не знаешь, уникальный ключ может состоять из нескольких полей... я невнимательно читал, но мне показалось, что ты не знаешь ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2003, 15:56 |
|
Терзают сомнения
|
|||
---|---|---|---|
#18+
к сож. пост получился cлижком громоздкий, тк хотелось подробнее раскрыть проблему. насчет уникального ключа из нескольких полей - я знаком с этим. конкат использую тк посчеты хитов и топиков ведуться в одной таблице (forum_info) и если уникальность (сесион_ид,топик_ид) необходима для хита, то это недопустимо для постинга юзера, который в одну сессию можег оставить в одном топик енесколько постов. вот почему пока испол. уникал. поле sid которое для хитов формируется как CONCAT(sid,topic_id,ФИКСИРОВАННЫЙ_недопустимый_номер_поста), а для постов как CONCAT(sid,topic_id,post_id). хотя тут возможны варианты. что касается хранения инфы о хитак в табл. forum_topic здесь видится 2 момента: 1 - нехочется делать апдейт таблицы при каждом просмотре топика. мне кажется инсерт в forum_info будет быстрее и менее чувствительно в плане одновременного доступа к таблице. 2 - теряется уникальность по сессии. (как например в данном форуме) один узер может многократно за сеанс нкликать кол-во хитов. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2003, 16:20 |
|
Терзают сомнения
|
|||
---|---|---|---|
#18+
совет. клади юзер и время последнего поста в спец поля таблицу топика - избавит от необходимости решения распространенной задачи "найти максимум из одной таблицы для каждой записи в другой". совет 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 лет и три года ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2003, 17:09 |
|
Терзают сомнения
|
|||
---|---|---|---|
#18+
к совету 1: клади юзер и время последнего поста в спец поля таблицу топика - избавит от необходимости решения распространенной задачи "найти максимум из одной таблицы для каждой записи в другой". это значит, что При добалении поста нужен еще один апдейт. А при удалении поста юзера, если он последний в топике, надо определить последнего юзера и снова сделать апдейт в табл. топиков. После чего удалить строку из табл. хиты_постингов, чтобы уменьшить счетчик постов юзера на 1. Я пытался избежать лишних апдейтов - щас вижу не уйти от этого. еще важно проверять согласованность данных о кол-ве постов и посл. юзере хранящемся в табл. топика и хитов_постинга и их реальнами значениями в табл. forum_post. к совету 2: хит - это новая сущность. для нее сделай отдельную таблицу хит по топику ==== ид хит (bigint auto_increment) ид юзера время ид топика если нужно считать хиты по постам, то еще одну таблицу хит по посту ==== ид хит (bigint auto_increment) ид юзера время ид топика ид поста одна из причин почему я полез в эти дебри (использование таблицы forum_info в стиле все-в_одном) явл то, что мне не хотелось при отображении списка форумов или топиков делать несколько сложных join'ов в селектах. а как же иначе получить таблицу инфы: Код: plaintext 1. 2. 3. 4. 5.
причем обрати внимание: инфа о последнем юзере Форума, требует нахождения последнего из всех топиков, принадлежащих данному форуму. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2003, 18:04 |
|
Терзают сомнения
|
|||
---|---|---|---|
#18+
к ответу на совет 1 абдейт неиндексированного поля происходит очень быстро, в отличие от любого инсерта. я бы инсертов больше избегал. насчет того, что при удалении поста придется переписывать - предполагаешь много удалять? ;) посмотри на этот форум, несмотря на то, что здесь все на мсскл с триггерами и всем остальным, при удалении постинга автора его общий счетчик постов не меняется, хотя можно было бы навесить триггер. ну и что, что останется имя и время того, кто последний запостил, хотя пост удален. нельзя с первой же версии сделать идеально. и Виндоус не сразу писался ;) кажется постепенно начинаю врубаться в идею таблицы форум_инфо и настаиваю, чтобы инфо о последнем посте в топик, форум и все форумы хранился в таблицах, соотвествующих каждой из этих сущностей. достигнешь быстродействия, приемлемого для веба, засчет того, что будет отображаться немного не та правда, которую ты хотел бы: если пост удален, все равно он был последним, это тоже правда, пусть отображается. что-то никто не подключается. может я чушь гоню, а меня никто не поправит... ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2003, 11:11 |
|
Терзают сомнения
|
|||
---|---|---|---|
#18+
достигнешь быстродействия, приемлемого для веба, засчет того, что будет отображаться немного не та правда, которую ты хотел бы: если пост удален, все равно он был последним, это тоже правда, пусть отображается. :-) принципе такой филлосовский подход, вполне приемлим, если даст выигрыш в быстродействии. Однако представь ситуацию: мы просматриваем профиль юзера, счетчик его постов - 5. хотим почитать что он пишет - а скрипт возвращ. что в базе его постов нет. у посетителя сайта сложится недоверие к инфе возвращаемой скриптами сайта. так же характерно, что удаляются обычто 'левые' посты, например, (пардон) возмет кто-нить ник=Конская_залупа и накидает постов. админ их удалит, но в списке топиков, будет красоваться ник злоумышленника. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2003, 11:52 |
|
Терзают сомнения
|
|||
---|---|---|---|
#18+
кол-во апдейтов-интсертов-селеков (с учетом других отличных от форума обращений к базе) хочется уложить в рамки хостинга приблизительно от10$ при возможно 5-10 пользователей одновременно нах-ся на сайте. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2003, 12:24 |
|
|
start [/forum/topic.php?fid=47&fpage=701&tid=1855782]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
40ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
72ms |
get tp. blocked users: |
1ms |
others: | 50ms |
total: | 205ms |
0 / 0 |