Forum Webscript.Ru
Программирование => Perl => Тема начата: от 13 Мая 2002, 07:23:31
-
Пишу интернет магазин на Perl, и тут возникла заминка с написанием навигации по категориям.
Список категорий хранится в таблице MySQL в таком виде:
--------------------------------------------------------
! номер ! номер ! название !
! категории ! родительской ! категории !
! ! категории ! !
---------------------------------------------------------
Нужно чтоб выводило список категорий. Например:
-------------------------------
Компьютеры
Комплектующие
Мониторы
Принтеры
Модемы
--------------------------------
После нажатия, к примеру, на комплектующие должно выводить:
--------------------------------
Компьютеры
Комплектующие
Материнские платы
Процессоры
Видеокарты
Память
Мониторы
Принтеры
Модемы
----------------------------------
После нажатия на процессоры должно выводить:
----------------------------------
Компьютеры
Комплектующие
Материнские платы
Процессоры
Celeron
P-III
Duron
Athlon
Видеокарты
Память
Мониторы
Принтеры
Модемы
----------------------------------
и т.д.
Интересует какой лучше алгоритм использовать для выборки показываемых категорий из таблицы, чтоб число обращений к таблице было минимальным? После выборки в каком виде лучше хранить данные, чтоб они занимали минимальное место в памяти и какой лучше использовать алгоритм для сортировки и отображения категорий?
При составлении алгоритмов необходимо учитывать, что количество вложенных категорий неограничено.
Может имеет смысл изменить структуру таблицы для хранения категорий?
Может кто-нибудь уже сталкивался с подобными задачами. Буду рад любым полезным советам...
-
Попробуй такое построение:
Основной упор делаеться на циферки
1-Название категории (Комплектующие)
1.1 Подкатегория (Память)
1.1.1 Первый элемент (16мб)
1.1.2 Второй элемент (32мб)
1.1.3 Третий элемент (64мб)
1.2 Подкатегория (Процесоры)
1.2.1 Пентиум
1.2.2 Селерон
1.2.3 АМД
2 - Компьютеры
2.1 Настольные
2.1.1 Winner-4
.
.
.и т.д
и вот этими циферками можно оперировать как тебе вздумаеться
-
Т.е. ты предлагаешь хранить данные в таблице: id, name. Где id - и будет номер категории? мне кажется что это будет более проблемный вариант....
-
Почему??? Даешь команду показать все что начинаеться с 2.
Вот тебе и Компьютеры........ и все что к ним ....
-
В таком случае будет показывать все вложенные подкатегории... А как быть в этом случае если надо вывести только до 2-го или 3-го уровня, а остальные не надо???
-
Файл базы для наглядности
menu.txt -----------------------
1::Компьютеры
1.1::Celeron
1.1.1::533
1.1.2::800
1.1.3::1200
1.2::Pentium
1.2.1::II
1.2.2::III
1.2.3::IV
2::Мультимедиа
2.1::Колонки
2.1.1::Genius
3::Прочее
3.1::Прочие товары
3.1.1::Ковер для мышки
и menu.pl
cut-----------------------
#!/usr/bin/perl
print "Content-type: text/html\\n\\n";
$buffer = $ENV{\'QUERY_STRING\'};
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
open D,"menu.txt";@menu=;close D;
$menus=$FORM{menu};
if (!$menus){&show_level_0}
if($menus=~s/cat//){ &show_level_1}
if ($menus=~s/sub//){&show_level_2}
sub show_level_0 {
foreach $line(@menu){
chomp $line;($category,$name)=split(/\\:\\:/,$line);
($catid1,$catid2,$catid3)=split(/\\./,$category);
if (!$catid2 ){print "$name
";}
}}
sub show_level_1 {
foreach $line(@menu){
chomp $line;($category,$name)=split(/\\:\\:/,$line);
($catid1,$catid2,$catid3)=split(/\\./,$category);
if (!$catid2 ){print "$name
";}
elsif ($catid1 eq $menus and $catid3 eq ""){
print " $name
\\n";}
}}
sub show_level_2 {
($c1,$c2)=split(/\\./,$menus);
foreach $line(@menu){
chomp $line;($category,$name)=split(/\\:\\:/,$line);
($catid1,$catid2,$catid3)=split(/\\./,$category);
if (!$catid2 ){print "$name
";}
elsif ("$catid1\\.$catid2" eq $menus and $catid3 eq ""){
print " $name
\\n";}
elsif ($menus eq "$catid1\\.$catid2" and $catid3 ne ""){
print " ссылка на $name
\\n";}
elsif (!$catid3 and $c1==$catid1){print " $name
\\n";}
}}
cut-----------------------------------------------
Громоздко конечно но пашет :)
-
Вообщем-то не очень громоздко, при желании можно уменьшить, но не в этом дело. Данные по категориям хранятся не в файле, а в таблице MySQL, но это тоже исправимо. Я в своей первой мессаге писал, что число вложенных категорий не ограничено, а в твоей проге оно понимает только до 3-го уровня вложенности, хотя это тоже поправимо. Но главное: твоя прога считывает все категории и потом выводит нужные, а это уже очень плохо, т.к. число категорий не ограничено. И еще: она нормально понимает когда категории расположены в файле по-порядку, но стоит их переставить местами и они выводятся абсолютно неупорядочненно....
to All: Я уже реализовал данную прогу и все работает нормально. Кол-во обращений к MySQL для считывания выводимых категорий равно вложенности категории... можно ли это как-нибудь еще уменьшить??? Как лучше хранить считанные данные (в моем случае используется два хеша) и как оптимально сортировать данные, чтоб избежать лишних циклов???
-
И еще: она нормально понимает когда категории расположены в файле по-порядку, но стоит их переставить местами и они выводятся абсолютно неупорядочненно....
разумеется! нужно проводить сортировку в файле после добавления новых категорий.
-
Это тоже очередной минус к проге, т.к. при добавлении категорий нужно каждый раз их сортировать. Хотя можно ее немного переделать чтоб она сортировала после считывания перед выводом меню на экран... Но все-таки самое хреновое в твоей проге это то, что она считывает в память все категории... Я попробовал реализовать алгоритмы сортировки при такой системе ведения категорий, imho, это менее удобная чем та, которая была изначально предложена мной. Хотя буду рад если ты сможешь мне доказать обратное... :)
-
Я не собираюсь тут ничего доказывать. Я предложил, показал как, дальше хочешь используй а нет - забудь. Сколько людей - столько мнений. Возможно мой алгоритм и не самый лучший.Возможно.....
Я бы вообще не мучился с развернутым меню. Удобно конечно но сам понимаешь, геморой.