Коллеги, подскажите, пожалуйста оптимальное решение. Есть 3 таблицы. В одной географические названия, в другой - номера (номенклатура) карт, в 3-й (связующей) - id названий и карт. В этой 3-й табл. может быть до 5 карт, соответствующих одномук названию. А может быть и нет ни одной записи-связи названия с картой. Нужно вывести список названий, а каждому названию - список соответсвующих карт, если есть записи в связ.табл. Попробовал выводить названия карт в цикле для каждого названия - см. ниже код ф-ии, которая запускается при выводе каждого названия. Но скрипт начал заметно тормозит уже при 200 записях. Может как-то можно проще решить эту проблему? Код (Text): $query = mysql_query("SELECT tm.id_toponim AS id_toponim, m.id AS id_map, m.name AS map FROM tm tm LEFT JOIN map m ON tm.id_map=m.id ORDER BY m.name ASC;"); while($q = mysql_fetch_array($query)){$maps[] = array('id_toponim' => $q['id_toponim'], 'id_map' => $q['id_map'], 'map' => $q['map']);} function maps($id){ global $maps; // вывод карт $c=0; for($i=0; $i<=count($maps); $i++){ if($maps[$i]['id_toponim'] == $id){ if($c>0) echo ', '; echo $maps[$i]['map']; $c++; } } }
Ты что, реально берешь ВСЕ записи, а потом в PHP в цикле выводишь одну из них? Танцевать надо от SQL запроса. Форматирование данных при выводе это дело двадцатое. Что ты хочешь сделать в этом скрипте?
SELECT tm.id_toponim AS id_toponim, m.id AS id_map, m.name AS map FROM tm tm LEFT JOIN map m ON tm.id_map=m.id WHERE tm.id_toponim = :id ORDER BY m.name ASC; mysql_fetch_array замени на mysql_fetch_assoc и тогда магия с = array(...) просто не нужна, делаешь = $q А в цикле убираешь if($maps[$i]['id_toponim'] == $id) т.к. других записей у тебя в принципе не будет. Сомнение вызывает и нужность функции c global внутри. Добавлено спустя 5 минут 4 секунды: Для такой мега задачи, как список значений через запятую, пригодилась бы group_concat. Тогда от скрипта вообще две строки останется
Так не пойдет. Выведутся лишь карты для одного названия, для которого задан WHERE. А мне нужно для всех. Я вывожу полный список названий с перечнем соответствующих для каждого названия карт. Попробую сформулировать задачу еще раз, с начала, на другую тему. Есть таблица title с полями id_doc, name, в которой находятся названия статей. Есть таблица tag с полями id_tag, name, где находятся названия тэгов. Есть таблица связей один ко многому tt с полями id_doc, id_tag - к одному названию статьи может быть много тэгов. Как наиболее оптимально вывести все названия статей и в скобках к каждому названию статьи вывести соотвествующие названия тэгов?
ошибка: таблица связей многие-ко-многим. один тег может быть у многих статей, одна статья имеет любое количество тегов. оптимально - специально для этой цели завести поле в таблице "статьи" типа text с именами тегов через запятую и выводить их. таблица связей нужна для поиска статей, а не для вывода тегов статьи. сайт stackoverflow работает именно так. Добавлено спустя 7 минут 45 секунд: не верю ты всегда выводишь все свои 200 названий и все номера карт к ним? и для этого 200 раз вызываешь функию, которая перебирает массив всех, б*ь, карт? походу всё еще хуже, чем казалось. открой для себя реляционные базы данных.
Иначе никак? Нужен будет и поиск по тэгам. Да, всегда. И записей будет не 200, а около 1000. Да, все не очень хорошо. Похоже, стандартная задача, но красивого решения что-то не могу придумать. И ты не очень хорошую вещь предлагаешь. Получается надо будеть забивать сотни раз тэг в виде текста скажем "Северная Америка" вместо ее id скажем в виде цифры 20? Это ведь не рационально. Всего-то разновидностей тэгов будет около 30 и они будут постоянно повторяться.
хех! если честно, 1000 или 30000 записей это не тот случай, когда что-то может тормозить -- это надо постараться все испортить. настройся позитивно! общий совет: не перекладывай манипуляции со множествами на пхп. для этого придуман язык SQL и сервера БД. задача пхп, в-основном, отформатировать вывод. Добавлено спустя 26 минут 12 секунд: эх, кто бы говорил! ))) зачем ты спрашиваешь совета, если не слушаешь?! я качнул себе дамп стековерфлоу за март 2013 для изучения и экспериментов. там записей порядка таблица Posts - 13млн таблица Tags - 32тыс таблица PostTags 14млн (а также Users 2млн, Comments 18млн, Votes 38млн и другие) так вот, в таблице Posts поле Tags выглядит как "<c><winforms><forms><type-conversion>". они пошли на эту избыточность из соображений рациональности. оптимизируются самые частые запросы. на сайте чтение происходит намного чаще, чем запись. да, при сохранении сообщения приходится писать теги еще и в текстовое поле. зато когда надо вывести пост, благодаря заложенной избыточности НЕ придется джойнить еще и таблицы PostTags и Tags! (а также НЕ расчитываются всякий раз заново счетчики голосов и НЕ джойнится Users ради никнейма!) видишь сколько букв я потратил чтобы показать тебе: есть best practices от очень серьезных разрабов. ты можешь не верить мне, хотя я побольше тебя понимаю, но эти товарищи на пару порядков умнее меня и такая структура отлажена годами. Добавлено спустя 19 минут 59 секунд: и про group_concat() ты тоже пропустил мимо ушей. а зря!!! с ней ты даже без избыточных полей можешь резко оптимизировать свой список-через-запятую. просто кардинально!
http://www.clearbits.net/creators/146-stack-exchange-data-dump реально торрент содержит не только stackoverflow, но и другие однотипные проекты этой компании. данные в виде xml, как и куда ты заимпортишь дело твоё Добавлено спустя 4 минуты 22 секунды: в интернетах есть варианты структуры для разных бд. достоверно узнать оригинальную структуру (MS SQL) можно через запросы в "песочнице": http://data.stackexchange.com/stackoverflow/query/new EXEC sp_tables EXEC sp_help '...' и, если мне склероз не изменяет, какие-то мелкие справочники я там же добывал, а не из архива. переложение на типы MySQL я делал сам, т.к. всё, что находил было либо фиговым, либо устаревшим - SO модифицируется периодически. не проси, не дам