Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
Доброго времени суток! Хотел попросить помощи в следующем вопросе. Есть 2 таблицы топики и посты: Топики: Код: plaintext 1. 2. 3. 4. 5. 6. 7. и посты в них: Код: plaintext 1. 2. 3. 4. 5. 6. 7. У постов, как вы видите есть флаг, который может принимать значения ТРУ и ФАЛСЕ. Так вот хочется 1 запросов вытащить следующее: Список (скажем из 10ти штук) топиков, их ИД, название а также общее число постов в каждом топике, число постов с флагом ТРУ и число постов с флагом ФАЛСЕ. Т.е. в итоге получить таблицу: id | title | post_quantity| true_flagged_post | false_flagged_post Разумеется можно было бы сделать обычный СЕЛЕКТ с 3мя вложенными в него селектами, которые считают то что надо. Но такой запрос идет уже приличное время. А если у меня много постов и топиков а я еще захочу отсортировать их по числу постов, то ууу... минуты будет запрос идти. Также если бы нужно было ТОЛЬКО число постов, то можно было бы соорудить запрос с использованием JOIN и GROUP BY: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Но вот что делать, когда мне нужно еще посчитать число постов с определенным значением флага? Если делать еще раз ДЖОЙН таблицы forum_post получается откровенный бред... Я пока только вижу выход держать все статистические данные (число таких постов, число сяких постов, общее число постов) в таблице топиков forum_topic и прямо оттуда их дергать. А чтобы обновлялось все четко поставить соответствующие триггерные ф-ции, которые пересчитывают нужные значения при обновлении таблицы постов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 12:27 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
Если делать еще раз ДЖОЙН таблицы forum_post получается откровенный бред... Почему это? Нормальная форма для sql-запроса.. Ну или функцию написать, чтобы перебирала всё подряд и считала суммы. Или вьюху вспомогательную, чтобы выводила в отдельных полях что-то для топиков 't' и 'f'.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 12:57 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
chAlx , напишите, если не затруднит... Мне никак не сообразить, я в общем то в SQL новичок совсем и непосредственно им не занимаюсь. Занимаюсь программированием на ПХП и соответсвенно мои знания SQL дальше SELECT и FROM далеко не уходят. Конечно что такое ВЬЮ и SQL ф-ция я знаю, но как сюда присобачить понимаю слабо. Фраза "функция, которая считала бы все для всех" сразу пугает, когда данных много запросы очень долго идут, не должен же юзер ждать 40 секунд пока база соизволит ему во всех топиках кол-во постов сосчитать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 13:03 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
С тремя джойнами получится как-то так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Это с большой вероятностью будет дико тормозить, но вдруг индексы сложатся так, что заработает.. С вьюхой вариант такой: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Ну и самое приятное -- то, что это всё же Постгрес ;) Так что на классическом SQL не зацикливаемся: Код: plaintext 1. 2. 3. 4. 5. Razoomкогда данных много запросы очень долго идут, не должен же юзер ждать 40 секунд пока база соизволит ему во всех топиках кол-во постов сосчитать... Да он успеет рефреш 20 раз нажать, и база упадёт ;) В плане построения онлайн-движка типа форума такие вещи, как счётчики постов в таблице топиков, весьма актуальны. Их можно и без триггера обновлять, если на каждую вставку/удаление использовать отдельную Постгресную функцию. В ней и права можно проверить, и квоты всякие -- в общем, куда красивее получится взаимодействие с БД, чем в классических мускульных движках. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 14:31 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
chAlx Вот 1й твой вариант не прокатывает. Попробуй сам если не влом и время будет, считает черт знает что... Я 2 раза писал, ну может конечно лоханулся гдето... но писал точь в точь как ты, 3 джойна с разными псевдонимами и их пересчитываем. А вот на счет, как я понял, уникальных возможностей ПГ, не знал про них, обязательно покурю... Теперь касаемо постов на форумах... То что я привел это пример просто. На самом деле у меня в проекте таких вещей масса, в частности пользователи - группы пользователей. Там совершенно аналогичные запросы нужны. Так вот есть в системе естественно опция вступления в группу, выход из группы и эти действия производятся в коде в 10ти разных местах и к сожалению не всегда работает один и тот же метод. Поэтому все эти методы нужно дополнять соотв. куском запроса, где вызывается эта ф-ция (будь она написана как метод ПХП со своим запросом или ф-ция ПГ). И когда будешь искать все места где изменяется число юзеров в группе - обязательно где-нибудь забудешь дописать пересчет. Поэтому и пришла в голову мысль юзать триггеры. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 15:05 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
Да он успеет рефреш 20 раз нажать, и база упадёт ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 15:06 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
- да черт с ним с рефрешем... ну ты станешь тусить на форуме где страница 40 сек грузится, я думаю вряд ли )))) Да, и спасибо за участие :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 15:06 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
Да, и еще... /* ех жаль что на форуме на этом редактирования своих постов нет - всю ветку уже загадил */ Хочется иметь возможность по всем этим полям отсортировать, возможно ли это будет сделать быстро в варианте номер 3? Например сортировка по числу постов, когда всех этих флагов нету и используется 1 JOIN и GROUP BY проходит быстро, а вот если писать для подсчета постов вложенный селект и сортировать по результатам его работы то это песня та еще... БД, как я понимаю, сначала ДЛЯ ВСЕХ топиков подсчитывает число постов, и лишь потом сортирует, даже если мне нужно выбрать 10 первых записей из 1000... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 15:11 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
RazoomВот 1й твой вариант не прокатывает. Ну, а у меня работает. Отладку вслепую твоего варианта оставляю опытным местным телепатам ;) RazoomПоэтому все эти методы нужно дополнять соотв. куском запроса, где вызывается эта ф-ция (будь она написана как метод ПХП со своим запросом или ф-ция ПГ). И когда будешь искать все места где изменяется число юзеров в группе - обязательно где-нибудь забудешь дописать пересчет. Мы же говорим про то, как правильно и хорошо сделать. А если есть неправильный и плохой проект, и его не хочется переделывать -- это саавсем другой вопрос. А когда всё-таки будешь переделывать -- пишешь пару хранимых функций add_user_to_group() и remove_user_from_group(), делаешь в них всё что надо и отнимаешь права у постгресных пользователей/групп делать это же напрямую с таблицами. Тогда никто точно не забудет, что поступает неправильно :) RazoomБД, как я понимаю, сначала ДЛЯ ВСЕХ топиков подсчитывает число постов, и лишь потом сортирует, даже если мне нужно выбрать 10 первых записей из 1000... Естественно -- как иначе она может узнать, что у 1001-го топика не окажется больше всего постов? А вообще, для всех случаев, когда "нужно выбрать 10 первых записей", настоятельно рекомендуется использовать ограничитель: LIMIT 10. Это может менять план запроса и вообще крайне позитивно воспринимается планировщиком. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 15:39 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
Задача решена... оказывается вот как надо было: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. // Тут группы и юзеры в них, ну да не суть важно. na - not_accepted users, юзеры которых не приняли в группу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 15:46 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
Просто distinct надо было навесить, иначе он считает произведение числа записей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 15:51 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
RazoomЗадача решена... оказывается вот как надо было: Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 15:58 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
Не нужно никаких дополнительных джойнов Считайте агрегаты примерно так: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2008, 18:07 |
|
||
|
Запрос - число сообщений в теме
|
|||
|---|---|---|---|
|
#18+
Спасибо всем за ответы, буду иметь в виду конструкцию с CASE. Однако решили все равно для подобных вещей держать дополнительное поле непосредственно в таблице групп и триггерными ф-циями это поле обновлять. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.09.2008, 11:09 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=35513321&tid=2004100]: |
0ms |
get settings: |
6ms |
get forum list: |
20ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
54ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
40ms |
get tp. blocked users: |
1ms |
| others: | 212ms |
| total: | 349ms |

| 0 / 0 |
