Сергей К.
1649 сообщений
#14 лет назад
Дело в том что, для местоположений, так же как и для категорий надо учесть и дочерние местоположения.
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("WebDesignStudio"):
Дело в том что, для местоположений, так же как и для категорий надо учесть и дочерние местоположения.

Так оба моих предложения, что вчерашнее, что сегодняшнее — учитывают дочерние категории и местоположения. С учетом любого уровня вложенности.
Вадим Т.
3240 сообщений
#14 лет назад
Пример. Развернутая таблица категорий category_expand
- id
- child_id

Допустим, мы имеем категории A и B, категория A имеет дочерние A1 и A2, и категория A2 имеет дочерние A21 и A22.
Тогда данные в таблице category_expand будут иметь вид:

A  - A1
A - A2
A - A21
A - A22
A2 - A21
A2 - A22


Цель такого подхода — развернуть дерево, то есть сделать его плоским, что позволит в дальнейшем использовать его в MySQL запросах.
(Кстати, например для Oracle это было бы не нужно, так как там можно сразу работать с деревом через CONNECT BY).
Сергей К.
1649 сообщений
#14 лет назад
tvv, я для дочерних категориях сделал иначе. Отдельная таблица
cat_id - идентификатор категории
childs - текстовое поле, в которой держу список дочерних категорий через разделитель, то есть
A | A1#A2#A11...
A1|A11#A12...
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("WebDesignStudio"):
tvv, я для дочерних категориях сделал иначе. Отдельная таблица
cat_id - идентификатор категории
childs - текстовое поле, в которой держу список дочерних категорий через разделитель, то есть
A | A1#A2#A11...
A1|A11#A12...

А как в этом случае запрос строите? Например, если нужно получить количества объектов в каждой категории первых двух уровней с учетом города? Неужели через условие LIKE?

(IMHO в этом случае имеет место нарушение реляционной модели, что негативно скажется на производительности, но может быть я не уловил Вашу идею, поясните пожалуйста, как собираетесь этот подход использовать).
Сергей К.
1649 сообщений
#14 лет назад
Цитата ("tvv"):
Неужели через условие LIKE
конечно нет.
Получаю запись для нужных категорий.
Средствами PHP разделяю, через explode
Так же для городов.
Дальше уже делаю COUNT. Правда еще не знаю как его составлять, что бы было хорошо.
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("WebDesignStudio"):
Получаю запись для нужных категорий.
Средствами PHP разделяю, через explode
Так же для городов.
Дальше уже делаю COUNT. Правда еще не знаю как его составлять, что бы было хорошо.

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

SELECT c.id, COUNT(o.id)
FROM category c
INNER JOIN object o ON o.cat IN (...) AND o.loc IN (...)
WHERE c.level <= 2
GROUP BY c.id;

Вместо троеточия подставите разделенный черед запятую id категорий и городов, которые составили в PHP скрипте.
Сергей К.
1649 сообщений
#14 лет назад
tvv, ага, примерно так думал делать, но не был уверен что будет работать. Надо попробовать. Но мой способ будет лучше или хуже вашего?
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("WebDesignStudio"):
tvv, ага, примерно так думал делать, но не был уверен что будет работать. Надо попробовать. Но мой способ будет лучше или хуже вашего

Однозначно Ваш способ лучше. Мне стыдно, что сам не додумался до такого решения.
Сергей К.
1649 сообщений
#14 лет назад
tvv, просто я такое сам еще не делал. На практике не проверял. Щас попробую внедрять и напишу что получилось.
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("WebDesignStudio"):
tvv, просто я такое сам еще не делал. На практике не проверял. Щас попробую внедрять и напишу что получилось.

Я поспешил с выводами. Для городов Ваше решение — самое то, а вот для категорий такое не пройдет.
Вадим Т.
3240 сообщений
#14 лет назад
В общем, пока что предложение такое. Для категорий использовать мое решение, для городов - Ваше.

SELECT c.id, COUNT(o.id)
FROM category c
INNER JOIN category_expand ce ON ce.id = c.id
INNER JOIN object o ON (o.cat = c.id OR o.cat = ce.child_id) AND o.loc IN (...)
WHERE c.level <= 2
GROUP BY c.id;
Сергей К.
1649 сообщений
#14 лет назад
tvv, ага. начал писать и столкнулся с проблемой.

на странице категорий много. Город то один, тут проблем нет. А вот категорий много и для каждой есть вложенности.
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("WebDesignStudio"):
tvv, ага. начал писать и столкнулся с проблемой.

на странице категорий много. Город то один, тут проблем нет. А вот категорий много и для каждой есть вложенности.

Ну да, поэтому дерево категорий и придется делать плоским.
Сергей К.
1649 сообщений
#14 лет назад
А если вот так?
Создать таблицу.

cats_loc_stats
поля
id
cat_id
loc_id
count_obj

то есть комбинация всех городов и категорий. Получится N(количество городов)*M(количество категорий, только что узнал что там планируется не 400 а до 1000) записей. Итого 400 000 записей. При добавлении объявления, затронуть выбранную категорию, и выбранный город и те что стоят выше. Везде добавить +1. Получится не большая нагрузка вроде. При удалении то же самое. Правда тут есть пакетное удаление объявлений(объектов). Так же усложняется логика при изменении категории или города для объекта. Но зато операция выборки получится очень быстрой.
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("WebDesignStudio"):
то есть комбинация всех городов и категорий. Получится N(количество городов)*M(количество категорий, только что узнал что там планируется не 400 а до 1000) записей. Итого 400 000 записей. При добавлении объявления, затронуть выбранную категорию, и выбранный город и те что стоят выше. Везде добавить +1. Получится не большая нагрузка вроде. При удалении то же самое. Правда тут есть пакетное удаление объявлений(объектов). Так же усложняется логика при изменении категории или города для объекта. Но зато операция выборки получится очень быстрой.

400.000 — это уже не мало для MySQL.
К тому же, это сейчас 1000 категорий и 400 городов (или сколько их сейчас), а завтра еще больше может быть.

IMHO можно не делать этой таблицы, а выполнять запросы с COUNT, но результат кешировать.
То есть, PHP скрипт будет сначала смотреть в кеш, и только потом делать запрос к БД, если это необходимо.

Кстати, а сколько ожидается объектов?
Сергей К.
1649 сообщений
#14 лет назад
Цитата ("tvv"):
Кстати, а сколько ожидается объектов?

надеемся сотни тысяч
Сергей К.
1649 сообщений
#14 лет назад
1000 категорий это максимум. Больше точно не будет. Городов не больше 700.
Сергей К.
1649 сообщений
#14 лет назад
А если сделать вот так:
использовать механизм кэширования в файл.
Для каждого города иметь свой файл. И в нем записать статистику для этого города в отношении ко всем категориям.
Получится столько файлов сколько городов. Файл города менять в том случае когда будет добавлено/удалено/перенесено объявления в/из этого города.
Конечно если город не первого уровня, надо будет так же изменить и файл которые являются родителями. Но тут в отличие от категорий, вложенность больше 4 вряд ли будет. Плюс работа с отдельными файлами будет быстрее чем с одной большой базой. При выборе города, читать из этого файла нужные категории и использовать.
Правда файлы будут не маленькие, и будет дублирование информации. Но думаю производительность выше.
Что скажете про такое решение?

Примерные расчеты по размеру файла:

1000 категорий, по 4 числа на каждую для ID и по 6 на количество(максимум)+разделители между категорий 999+разделители между ID и количества 1000 = примерно 4000+6000+1000+1000 = 12 000 символов максимум. Это в том случае если для одного города, будут объявления во всех категориях и их на столько много в каждой категории. А на самом деле, в практике, думаю будет не больше 2-3 тысяч знаков. А это файл размером в 2-3 кб. Думаю его обработка не составит больших проблем для процессора.
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("WebDesignStudio"):
Для каждого города иметь свой файл. И в нем записать статистику для этого города в отношении ко всем категориям.
Получится столько файлов сколько городов. Файл города менять в том случае когда будет добавлено/удалено/перенесено объявления в/из этого города.
...
Что скажете про такое решение?

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