Белогривые лошадки
Про облако тэгов хотелось бы понудеть.
Движки, которые выводят облако тэгов на каждой странице, не кэшируя его — ущербны. Например, Wordpress генерирует страницу «пост с комментариями» с помощью 28 (!) запросов к базе данных. Поэтому посещаемые сайты на wordpress-е (не будем показывать пальцем) тормозят безбожно.
Совершенно же логично, что для генерации поста с комментариями — например, в этом блоге — нужно максимум три MySql запроса: 1) вывод поста, 2) вывод комментариев, 3) вывод навигации «Вы сейчас здесь».
Облако тэгов, само по себе — идиотская идея и ненужная фигня, типа календарика. Основная ее «фишка» в том, чтобы вывести список и по алфавиту и по «важности» (выделив это размером).
Тут и кроется самый смешной нюанс — тэги у всех разные. Натурально, разные слова. Начинаются на разную букву. У кого-то ключевое слово «имбецилы», у кого-то — «идиоты», а тема-то одна и та же. Не говоря уже о том, что везде наблюдается смесь английского и русского, которая довольно нелепо сортируется по алфавиту.
От сайта к сайту «оно всё разное». Запоминать ваши тэги/ключслова ни один посетитель не будет, не обольщайтесь. Сортировка по алфавиту бессмысленна.
Сортировка по дате чуть более осмысленна, но а) интуитивно не понятна, б) часто пересекается с сортировкой по популярности (логично же, что чем больше постов по теме X, тем больше вероятность, что про эту тему недавно писалось, в) последние ключслова и так находятся под заметками на первой странице.
«Там решено было цветом выделять последнее, хорошая мысль» — мысль вовсе не хорошая. Цветом нужно выделять только посещенные ссылки. Это принятно, интуитивно понятно, и, что самое главное — это гораздо полезней. Разноцветные ссылки — никому не понятное уебище. Даже если и подписано «Bright Color = Newer» — я захожу на сайт читать, а не оттенки цвета угадывать.
То же самое и с размерами — размеры шрифта — показатель на самый точный. Сколько разных и различимых размеров можно запихать в одно облако? Десяток максимум. Сложнее всего быстро пробежать все «облако» глазами, ибо глаз в любом случае застревает на самых крупных элементах и дальше не идет. И это не плюс, это минус.
Никому никогда не интересны все ключслова. Потому что часто бывает ситуация, когда есть «случайные» ключслова, принадлежащие одному-двум документам.
Как надо
В своем личном блоге проще всего отобрать штук пять ключслов, которые «наиболее характеризуют». И разместить их любым удобным способом. Например, как у меня справа. Вам самому безо всякой «автоматизации» лучше знать, какие ключслова «круче», без привязки к их частоте.
На массовых «социальных сервисах» облако тэгов неинформативно, но нужно для того, чтобы круто выглядеть, и чтобы пальцем не показывали. И для того, чтобы направить леммингов по ими же протоптанной тропинке. В этом случае можно вместо «букав» просто использовать прямоугольники разных размеров и цветов, так как кликнут все равно на тот, который больше. А надписи никто не читает.
Bonus track
Хранить тэги в таблице надо так:
1. В таблице с постами. Отдельное поле «ключслова через запятую».
2. В отдельной таблице связей, которая имеет вид «ID поста — ID тэга».
Это не два способа, а один, то есть хранить надо и так и так одновременно. Ценой небольшой избыточности информации мы получаем гораздо больший простр для. Минус только один: при редактировании надо редактировать и то и то, разумеется.
И про баб
Весь следующий месяц меня монетизирует cайт бесплатных знакомств. Не знаю, видели ли вы его, но я уже раз в пятый натыкаюсь. Лемминго-ориентированный интерфейс (это плюс), две кнопки «я б ей вдул» и «сам ей вдуй!».
Мне интересно — стоит ли за этим какой-нибудь хитрый алгоритм, или просто rand()? Был же где-то сайт, на котором тебе показывают картинки, а ты выбираешь «нравится» или «не нравится», а в конце о твоей личности делают некие выводы. Находят латентную пидерастию, например.
Вдруг и там так же?
На эту заметку ссылаются:
провокация второго уровня, чтобы заставить ткнуть в монетизирующую ссылку интеллектуалов?
У тебя детство было, да?
на я.ру на всякий случай тоже кликать не стал
Как-то тут неубедительно вышло :-)
По мне, так вполне достаточно хранить теги в отдельной таблице, а связывать с постами через таблицу связей (т. е. твой 2 способ). А так, к примеру, простое переименование тэга повлечет за собой необходимость правки всех постов, в которых он присутствует… Или нельзя поставить спец. флаг и просто скрыть какой-либо тэг (ну например, в том же облаке нет смысла показывать тэг, привязанный только к одному посту), чего, кстати, в ЖЖ нет…
P. S.: Жестко ты с посетителями… «Лемминги» )
У меня просто хитрым способом сделано: при выводе тэгов, рубрик и прочего дополнительная таблица не дергается и дополнительные запросы не создаются. Типа такого: http://nudnik.ru/entry/1492 В «регистре» вообще были все эти ключевые слова без базы данных вообще.
То же самое и с количеством комментариев — никто не сомневается, что хранить их надо так же.
Но вообще да, второго способа должно хватить большинству. =) Просто сразу появляется соблазн считывать их отдельным запросом. Как иначе объяснить по 20+ запросов на страницу — я не знаю.
А лемминги — очень милые грызуны.
И что, по-честному, оно себя оправдывает? По-моему, тэги по определению второстепенны, стоит ли тут структуру наворачивать?..
А 20 запросов на страницу получилось скорее всего из-за огромного количества разнообразных служебных запросов. Я раньше тоже возмущался по этому поводу, но когда сам окунулся, понял, что тут очень непростой компромисс: между функциональностью и количеством запросов иногда почти прямая зависимость…
Кэш — панацея ;)
Функциональность-то одна и та же: блог с комментариями. Откуда там wordpress столько запросов берет — я не знаю.
Ну и кэш не панацея, хотя вещь хорошая.
Я с первого раза заметил, только прочитал позже.
P.S. Дима, а зачем мне на почту приходят _мои_ комментарии? Может, только чужие надо присылать?
Только его надо на 90 градусов повернуть по часовой стрелке. И отсортировать не по алфавиту, а по частоте.
Если бы на shared-хостингах «за 10 баксов» везде вместо php стояла бы java, то оно раком вставало бы всё даже чаще, чем сейчас.
Hibernate что ли?
Не факт. Java кешировала бы все по-умному.
Demon
Не обязательно. EJB тоже.
Да, я не пишу на чистом JDBC и другим не желаю.
Ты хотел сказать Persistence API?
Hibernate — говно, кстати.
Hibernate, например, не позволяет думать о запросах. В результате выборка 100 записей из таблицы может выглядеть как 100 запросов по одному ряду. Смотрел на это и не знал, что и думать.
Не нужно бросаться умными словами. Persistence API — часть EJB3, а я еще и EJB2.1 имел ввиду, ага.
Persistence API, кстати, построен на Hibernate, который гавно (а что не гавно? чистый JDBC?).
Автор
Небось, загнулся он потому, что чат был построен на Java-applets и разработчики не подумали о потоках.
Hibernate, например, позволяет думать о запросах. Читайте документацию.
Да я тут не вижу никаких умных слов. Ну и я вопшемта вопросы задавал, а не словами бросался. Видишь у меня там знаки вопроса стоят? То-то же!
> а что не гавно?
ADO.NET. Только не упади -)
> Hibernate, например, позволяет думать о запросах.
Это ты про native SQL что ли? (Вот видишь. Ты так непонятно пишешь, что постоянно приходится спрашивать всякое.)
Это откуда такие сведения, кстати?
Не-а, не надо. Их можно в том же запросе получить, в котором выбирается текст записей:
SELECT [bla-bla-bla], count(if(posts.id = comments.post_id, 1, NULL)) FROM posts, comments WHERE [bla-bla-bla]
Домашнее задание: отсортировать посты по количеству комментариев.
Очевидно: добавить в конец запроса ORDER BY N DESC, где N — номер «столбца» count(if(…)) в запросе.
Только непонятно, чем такой «один запрос» будет оптимальней, чем первоначальные три. (Да, я знаю, на 10% быстрее. Но вариант с избыточностью — на 200% быстрее.)
Оправдывает, оправдывает. Я о чем и говорю.
Недостатки такой избыточности очевидны: необходимо везде вставлять UPDATE, где может меняться общее количество комментариев.
Конечно, существуют ситуации, когда такая избыточность оправдана (например, преобразования id url). Однако дополнительно хранить количество комментариев не стоит.
Apazhe.net иногда лежит с «CPU quota exceeded». Это тоже явно не канал.
В таблице с тегами хранил бы количество связанных постов, чтобы потом выводить его в скобочках и сортировать теги по частоте.
Браво!
Даже скопировать не могут нормально, идиоты.
А, дотнетчик. Предупреждать же надо!
Я о джаве говорю, да. там Hibernate, а не nHibernate. Говно ли nHibernate — не знаю, вполне может быть что гавно, как и весь дотнет.
Сам дотнетчик!!!
> Я о джаве говорю
Вот и я о ней. Ты читай внимательно, если что непонятно — спроси.
> там Hibernate, а не nHibernate
Что то, что это — одинаковое говно.
Да ты чо! Категоричность в суждениях, говоришь? Ща я тебе покажу категоричность в суждениях. И вопросов не буду задавать, хуле.
> Persistence API, кстати, построен на Hibernate
Вот это, например, откровенная чушь, заставляющая усомниться в адекватности автора.
> Hibernate, например, позволяет думать о запросах.
Это тоже пиздеж. Потому что если использовать native SQL, то непонятно нахер было вообще брать Hibernate. Кстати, отличной характеристикой этого гибернейта является как раз наличие native SQL: мы хотели абстрагироваться от базы данных, но у нас ни хера не вышло.
> Небось, загнулся он потому, что чат был построен на Java-applets и разработчики не подумали о потоках.
Это вообще шедевр. Если слать 100 запросов в 2 потока по 50 в каждом — это в 2 раза снизит нагрузку на сервак! Занимательная потоковая арифметика для тупых. Плакалъ.
> Вот это, например, откровенная чушь, заставляющая усомниться в >адекватности автора.
У EJB3 очень много взято из Hibernate, ага.
> Это тоже пиздеж. Потому что если использовать native SQL, то >непонятно нахер было вообще брать Hibernate. Кстати, отличной >характеристикой этого гибернейта является как раз наличие native >SQL: мы хотели абстрагироваться от базы данных, но у нас ни хера >не вышло.
Конфигами и тд Hibernate таки можно настроить, чтобы он составлял примерно те запросы, что нам нужно.
> Это вообще шедевр. Если слать 100 запросов в 2 потока по 50 в >каждом — это в 2 раза снизит нагрузку на сервак! Занимательная >потоковая арифметика для тупых. Плакалъ.
Если сервер обрабатывает все запросы от всех апплетов в одном своем потоке — да, он может загнуться.
«Взято из» и «построен на», это как бы совсем разные вещи, ты не находишь?
> Конфигами и тд Hibernate таки можно настроить
Ну так. Вместо SQL получаем HQL, который дальше нужно доводить некомпилируемыми конфигами, причем не факт, что получится. Это и есть 100% чистый навоз.
> Если сервер обрабатывает все запросы от всех апплетов в одном своем потоке — да, он может загнуться.
Откровенную чушь-то не надо писать. Если бы сервер обрабатывал все запросы в одном потоке, то это был бы очень тормозной сервер, который бы никогда не падал. Ты вообще в курсе… я не знаю… жизненного цикла сервлета, например?
Ясно, что в виде функции. Но функцию эту нужно вызывать, как минимум, когда посетитель оставляет комментарий, когда комментарий делается невидимым/видимым или удаляется в админке.
Быть может, запрограммировать кеширование количества комментариев в таблицу с постами действительно не так сложно. Целесообразность такого шага зависит от множества других факторов.
первые два пункта замнем для ясности.
> Откровенную чушь-то не надо писать. Если бы сервер обрабатывал все запросы в одном потоке, то это был бы очень тормозной сервер, который бы никогда не падал. Ты вообще в курсе… я не знаю… жизненного цикла сервлета, например?
Представь, сервер тормозной, а мы в апплете поставили, что если сервер не отвечает 5 секунд, мы запрос переотсылаем.
И сервелеты тут ни при чем, нафиг тут сервлеты ваще?
Автор
> Да вы заебали.
А ты отпишись от комментов!
Понимаешь, такие пассажи, они только выдают твою некомпетентность.
1) Если сервер не отвечает — значит он уже лежит.
2) Есть такая вещь — timeout называется.
3) Слать запросы через каждые 5 секунд — это реализация стратегии типа «баран».
> И сервелеты тут ни при чем, нафиг тут сервлеты ваще?
Жизненный цикл сервлета хорошо иллюстрирует то, как устроена обработка запросов на сервере с точки зрения мультипоточности. Поэтому
> Если сервер обрабатывает все запросы от всех апплетов в одном своем потоке — да, он может загнуться.
- это бред.
Это еще почему? Тебе что места в БД жалко?
Вообще говоря, развивать оффтопиковую дискуссию в чужом блоге (и не с его хозяином) — это как бы невежливо.
Это с каких херов? Все только этим и занимаются!
> 3) Слать запросы через каждые 5 секунд — это реализация стратегии типа «баран».
Мне кажется, ты забыл, о чем мы тут разговариваем. Я напомню. Мы обсуждаем кривой чат, который падал на 20 пользователях. Я тебе говор: «он мог упасть, потмоу что у разработчиков руки кривые, и они могли написать так-то и так-то». А ты мне: «да нет, у разработчиков руки не кривые, они же не бараны!». Ну, и где тут логика?
И да, если ребята писали сами свой сервер (что вполне логично, там же просто чат), они могли и не знать, как там жизненный цикл сервлета выглядит и тп. Еще раз: мы говорим о чьем-то кривом софте. Если ты знаешь, как оно там было написано и почему падало — расскажи, не томи.
Я поэтому и попытался их урезонить. Не внемнут.
Вот ты — не знаешь, да. Если бы ты знал — ты бы ничего не говорил про однопоточную обработку запросов, которая, якобы, кладет сервак.
> Мне кажется, ты забыл, о чем мы тут разговариваем. Я напомню. Мы обсуждаем кривой чат, который падал на 20 пользователях.
Это ты забыл. Мы говорим о том, что половина java-related технологий — говно (см. Hibernate). Падение чата на 20 пользователях — это просто иллюстрация говнистости.
> И да, если ребята писали сами свой сервер (что вполне логично, там же просто чат)
Что, свой сервер приложений специально для чата писали? То есть по-твоему это нормальное предположение? [истерически ржет, падает под стол] Не, с меня хватит, я больше не буду этот бред обсуждать.
Чо?
Совсем своими сервлетами моск затрахали.
> Что, свой сервер приложений специально для чата писали? То есть по-твоему это нормальное предположение? [истерически ржет, падает под стол] Не, с меня хватит, я больше не буду этот бред обсуждать.
Да, єто нормальное предположение, поверь мне.
Автору: если хочешь, мы ко мне в ЖЖ перейдем около джавы сраться. В принципе, давно пора.
Аллилуйя! Ребята, ну нельзя же так, в самом деле. Закроет Дима комменты, и всё, опять придётся синдикацию комментировать.
Точно. Иди к себе в жж и там устраивай цирк с конями.
> Точно. Иди к себе в жж и там устраивай цирк с конями.
Ггг, ага, по типу того, какое отношение имеет жизненный цикл сервлета к многопоточности.
Вижу я, вижу, что ты об этом сегодня, наконец, прочитал и ничего не понял. Объясняю: каждое обращение к методу service является частью жизненного чикла сервлета и происходит в отдельном потоке. 10 обращений — 10 потоков. Похожим образом работают jsp, web services и т.д. То есть «сервер обрабатывает все запросы от всех апплетов в одном своем потоке» — это чушь несусветная.
Короче, ты меня уже задолбал своим невежеством. До новых встречь.
Сервлету похер, дергают его в отдельном потоке или нет. У него есть метод service — и все. А будет этот метод дергать один и тот же поток (что можно выставить в настройках сервера приложений) или куча разных — это сервлет не волнует. Это называется «Хороший дизайн».
Продолжай кидаться прочитанными фразами из учебника «Джава для полных идиотов за 180 дней» дальше.
Я же сказал — свободен. Ты даже для флейма слишком туповат.
(Всё-всё, автор, это последний комментарий)
Не, Дима, коммент я напишу, но по Java выскажусь лучше в другом месте. Удержусь. Еле еле. Но удержусь. :)
Для тебя могу сказать, что у меня на Java написан код игры. Там на Java чат/боёвка/инфа о персонажах и еще какие-то лабиринты. Проект не мой, я помогал делать, и сделан не идеально. Но пару сотен пользователей и несколько тысяч ботов держит, не жужжит… Так что чат, что ты видел, написан тем же быдлокодером, что и «тырнет магазин, сам пысал, за тры дня».
Можно хорошо писать даже на лиспе или прологе. Если думать.
> программу пишут не API, а таки программисты
Я эту мысль и пытался высказать. И предлагал ответ: «программисты тупые, например, они могли думать так-то и так-то». Меня не поняли, естественно.
Мы сейчас делаем довольно большой проект для одной очень крупной компании. У них там, естественно, есть свой IT-отдел, который продавил следующие технические решения: Hibernate, Spring, JSF, Portlets. Идти против заказчика, как ты понимаешь, можно далеко не всегда. Вбили они себе в голову, что им нужны edge-cutting enterprise solutions – все, тушите свет. Hibernate тормозит, Spring тормозит, JSF слишком сырой – клиентщики словили пару отличных граблей из-за его багов, с портлетами JSF скресить получилось только через жопу. Закономерный итог: показ попапа с подсказкой занимает 10 секунд, потому что при этом отправляется около 30 запросов в базу. Это не потому что мы так написали, это потому что так вот работают все эти замечательные API.
Так вот. Программу пишут, конечно, программисты. Однако выбор API существенно влияет на. А поскольку до хрена леммингов пребывают по воздействием заклинаний типа «enterprise», «abstraction layer» и т.д., то выбор эих API как правило – чудовищен. Поищи на job.ru по ключевому слову Hibernate или Struts – много интересного узнаешь.
> Для тебя могу сказать, что у меня на Java написан код игры. Проект не мой, я помогал делать, и сделан не идеально.
Понимаешь, если все, что ты сделал на Яве – это код небольшой игрухи, то у тебя банально недостаточно опыта.
> Можно хорошо писать даже на лиспе или прологе. Если думать.
[морщится] Пролог-то сюда зачем приплетать? Cпецифический язык со специфической областью применения.
Давай я тебе покажу проект, над которым работаю я. Hibernate, Spring, JSF, Oracle. Проект выдерживает тысячу пользователей одновременно, будучи запущенным на одном сервере.
Ты это… ври-ври, да не завирайся. 1000 одновременных запросов уронят, например, jboss.
Типичная практика — порядка 50 пользователей на сервер, несколько серверов, лоад балансер.
> Давай я тебе покажу проект, над которым работаю я.
Покажи.
Там Tomcat, JBoss здесь нафик не нужен.
Я тебе говорю цифру, которую мне QA сказал, он тестировал на нагрузку, не я.
http://helmetstohardhats.org/
Автор, сотри мой комментарий после прочтения, пожалуйста.
Какая разница. Tomcat — часть Jboss.
> Я тебе говорю цифру, которую мне QA сказал, он тестировал на нагрузку, не я.
Так не говори, если не знаешь!
Если интересно, вот познавательная статья про load balancing для Tomcat — http://people.apache.org/~mturk/docs/article/ftwai.html
> Хехе, там еще не рабочая версия дежит, какая-то заглушка на ASP.
Примерно я понял. По сравнению с тем, что делаем мы, это — маленькое и простое приложение.
> Какая разница. Tomcat — часть Jboss.
И что дальше? А еще там есть log4j, так что теперь, что JBoss, что log4j — похер?
> Так не говори, если не знаешь!
Я знаю, о чем я говорю. Тестировалось без load balancing, на одном сервере.
> Примерно я понял. По сравнению с тем, что делаем мы, это — маленькое и простое приложение.
(смеялся)
Это говорит только о том, что ты не знаешь устройство Jboss.
> Я знаю, о чем я говорю.
Бугага. Все твои посты с самого начала — это демонстрация потрясающего невежества.
Учи матчасть, короче.
> Это говорит только о том, что ты не знаешь устройство Jboss.
Да-да. Это ведь я сказал о том, что нет разницы, что мы используем — JBoss или Tomcat.
Зажигай дальше.
Вот так будет гораздо лучше:
SELECT [bla-bla-bla], (SELECT count(*) FROM comments WHERE posts.id = comments.post_id) FROM posts WHERE [bla-bla-bla]
Поле post_id в таблице comments делается индексом. Тогда внутренний запрос к этой таблице не обращается вообще, использует только индекс.

26.09