|
|
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Добрый день всем, кому еще не надоело отвечать на глупые вопросы :0)) и тем, кому надоело - тоже добрый день! Имеется многоуровневая партнерка. В БД структура сохранена нормально - у каждого юзера есть "вышестоящий". Возможно ли составить такой запрос, чтобы одним запросом можно было получить всю структуру юзера на всю глубину или хотя бы на заданное количество уровней , например на 7? Я могу сделать с помощью рекурсивной функции на РНР, но запросов получается много (даже слишком :0(( ), а вот хотелось бы одним запросом... или это из области фантастики? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2012, 00:54:39 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
нужен фак! (пардон май френч). Товарищи специалисты, напишите фак, плиз! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2012, 01:38:19 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
trew, модераторам или автору bochkov: плиз, добавьте в тот топик (что по ссылке) решение на переменных с одним parent_id !!! Или ссылку туда на весь топик "массивы в ..."!!! Ну оговорите его, что "не для слабонервных"... но красиво же как! потеряется же... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2012, 12:00:48 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirint, древовидную структуру, всеравно надо делать на клиенте. При чем можно обойтись без рекурсии ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2012, 16:02:55 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Arhat109модераторам или автору bochkov: плиз, добавьте в тот топик (что по ссылке) решение на переменных с одним parent_id !!! Или ссылку туда на весь топик "массивы в ..."!!!Ссылку добавил. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2012, 16:28:41 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
artaslabirint, древовидную структуру, всеравно надо делать на клиенте. При чем можно обойтись без рекурсии Перечитал я раз 10 тот ФАК, все равно чайником остался :( artas, а что ты имеешь в виду - "делать структуру на клиенте"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 00:13:08 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirint, Тогда задавайте конкретные вопросы по факу... что осталось непонятным. Вполне возможно, что "вам осталось сделать первый шаг". :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 07:06:20 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Arhat109, ну, прежде, проблема в моих небольших знаниях в мускуле - я не знаю условных обозначений, например ":=" и "@", даже не знаю - куда записать процедуру, приведенную Вами как пример. Обычно я все делаю в РНР скрипте, но это можно прочитать (или догадаться :) ) А вот конкретнее: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 1) как формировать level для таблицы партнерской программы, когда люди в разные места структуры добавляются не систематично? Вообще, для таких условия построения структуры - подходит ли эта процедура? 2) как в запросе задать глубину требуемой части дерева? 3) возможно ли таким подходом делать подсчеты? 4) возможно ли это использовать для INSERT по определенным правилам? Спасибо за внимание! (к нашим проблемам) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 10:07:35 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirint, это можно считать в проце-дурой, но в том виде как есть - это просто набор запросов к Мускулю, каждый из который завершается ; и они подаются последовательно в одной сессии "подряд": 1. SET @C=...; -- устанавливаем переменную сессии с именем "С" в это значение. @ -- признак сессионной переменной и только. Тут - просто такой комментарий. И только. В целом - не нужно. 2. SELECT ... ; -- запрос. Просто он хитрый и поэтому отформатирован в несколько строк, чтобы было понятней "чего в нём спрашивается" у Мускуля. И только. 3. строка с # -- тоже комментарий. Только с того места, где оно стоит и до конца строки. Ничего больше. Внутри запроса также используются переменные сессии, но в запросе значения им присваиваются через := и только. Что делает запрос? В секции FOM - указано объединение подзапроса с ником 'dummy' и таблички с именем tree. Как видно, подзапрос тупо присваивает сессионным переменным начальные значения... и всё. Там, в качестве начального значения указано search_num -- типа параметр процедуры... при одиночном запросе, можно просто прописать требуемую константу - идентификатор, как стартовый узел поиска поддерева. Фсё. Ничего больше в секции from - нету. Разве что "прибит гвоздиком" (force index(primary key) первичный ключ как пожелание, сканировать записи строго в его последовательности. В секции Веры сказано "копать до тех пор, пока очередной родитель ещё присутствует в переменной @array". Фсё, тожа. В секции select указано, что для каждой найденной записи (родитель которой есть в @array, а изначально там исходный узел из подзапроса установки переменных!) отдай как поля: 1. Уровень записи 2. Текущего родителя, а заодно: если предыдущий родитель был другим, то 2.1. удали его из переменной @array 2.2. , запомни текущего на будущее 3. Собственно идент узла (как дитенка), а заодно: если текущий родитель есть в списке, то: 3.1. добавь меня в список возможных родителей (а вдруг у меня есть потомки! -- вот тут-то и создается список проверяемых узлов, связанных с первым, "внезапно" :) Всё. Ничего больше отдавать не требуется. Как видим, исходная таблица - тупо сканируется в порядке первичного ключа, который составной от верхнего уровня к листьям и с меньшего родителя к большему. Если кроме первичного, у таблички других ключей нет, то и ладушки. Работать будет. А вот ежели есть, то не факт: мускуль запросто может "опимизнуть" по другому индексу и порядок сканирования будет нарушен.. со всеми последствиями. Об чём в факе и было указано как существенное ограничение решения, дополнительно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 11:39:34 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirint, теперь на вопросы внизу поста (а то и так много): 1. level - это тупо номер уровня, +1 к корню на каждом уровне. Поскольку добавляя запись в табличку, вы всегда её привязываете к некоторому узлу, то по факту - уровень новой записи - это уровень родителя+1. 2. Добавить соответствующее условие в часть Веры: И "уровень не больше заданного" как-то так. 3. ?!? а почему нет? Результат - список узлов данного поддерева от заданного узла... а куда и с чем вы его считать будете... пробуйте. Все равно в надзапрос заворачивать... 4. insert .. select() ? почему нет? я - не пгобовал за ненадобностью... но при переносе поддеревьев, возможно и актуально. Дерзайте. ИМХО есть в факе: запрос оригинальный, работает быстро... но имеет существенные недостатки (отсутствие гарантии выборки строго по индексу)... то есть для очень простых и/или лабораторных испытаний - полезно. А для "боевого применения", я бы выбрал запрос с подселектом. Он значительно медленнее, но зато не страдает фигней. ... хотя, для простых поисков поддеревьев он у меня работает в таком виде... и давно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 11:51:14 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Arhat109labirint, это можно считать в проце-дурой, но в том виде как есть - это просто набор запросов к Мускулю, каждый из который завершается ; и они подаются последовательно в одной сессии "подряд": Большое спасибо - вся ясно! Только еще вопросы :) 1) в моем случае эту таблицу действительно можно сделать с таким одним составным индексом. А есть предположения или, еще лучше, знания - как подобный запрос поведет себя с JOIN на другие таблицы? 2) есть ли в MySQL возможность какой-либо командой временно "отключать" индекс, подобно как FORCE INDEX, только наоборот :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 16:23:23 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Arhat109labirint, ИМХО есть в факе: запрос оригинальный, работает быстро... но имеет существенные недостатки (отсутствие гарантии выборки строго по индексу)... то есть для очень простых и/или лабораторных испытаний - полезно. А для "боевого применения", я бы выбрал запрос с подселектом. Он значительно медленнее, но зато не страдает фигней. А этот - с подселектом - какой из показанных в ФАКе? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 17:06:26 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Arhat109, попробовал я сделать составной первичный ключ и получил от мускула "желтую карточку" : #1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key правда делал я это не при создании, а ALTER TABLE, может в этом причина? Сейчас попробую создать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 22:42:11 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Arhat109, не дает создать таблицу с таким индексом :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 22:49:59 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirintArhat109, не дает создать таблицу с таким индексом :( создал я таблицу с одинарным primery key ('id') и начал пробовать заполнить ее как у Вас сделано. Тоже не получается :( Мускул ругается на все подряд. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2013, 23:54:55 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirint, Работа с переменными -- дело непростое. И не то что сложно для понимания, а то что сама база под этим делом неустойчивая С нуля вы потеряете больше времени чем получите результат. Алтернатива -- сделайте на кленте. Если надо найти дерево одного конкретного родителя, то ну 10, ну 15 поколений -- запросы по индексу дают пару милисекунд, ну 50 милисекунд потратите на это дело в медленый день. За что боретесь? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2013, 04:04:36 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirint, упс... только сейчас увидел. Сразу на всё: 1. 1) в моем случае эту таблицу действительно можно сделать с таким одним составным индексом. А есть предположения или, еще лучше, знания - как подобный запрос поведет себя с JOIN на другие таблицы? 2) есть ли в MySQL возможность какой-либо командой временно "отключать" индекс, подобно как FORCE INDEX, только наоборот :) При создании первичного и единственного составного индекса, автоинкремент там надо отключать. Практика показала, что инкрементировать можно на клиенте кучей разных способов, начиная от ведения таблицы универсального идента... типа uid. ... уже столкнулись. Нормально ведет, например так: SELECT destination.* FROM your_table AS destination JOIN( # втыкаем сюда это чудо как подзапрос ) AS derived ON derived.child_id = destination.ident # Where, group by и т.д. дальше по вкусу... 2. Я такой не знаю. Больше того, и форсеиндекс - тоже всего лишь рекомендация... он не всегда прибивает индекс к запросу... 3. "с подселектом" -- там, где-то чуть выше, который определен как запрос Бочкова. Он практически такой же, но на каждом элементе делает подчиненный запрос к таблице для поиска всех потомков, что гарантирует их корректный выбор. Но это значительно дольше. 4. Этот вариант запроса - быстр и корректен, только при наличии составного индекса и его использовании. За всё надо платить. Снесите автоинкрементный индекс и признак автоинкремента и создайте составной индекс в заданном порядке полей, именно так (level, parent_id, id)... и попробуйте на тестовой табличке... потом попробуйте Бочковский вариант и оцените разницу в скорости... если она вас устраивает - предпочтите бочковский вариант. Он существенно устойчивее. И, только если вам нужна бОльшая скорость реакции - вот тогда, продолжайте экспериментировать дальше с этим вариантом. Особое внимание - на корректность использования индекса (без него может стать неверно, если в таблице записи вставляются не по порядки и/или удаляются со временем). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2013, 07:05:57 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirint, Просмотрел фак ещё раз. Вот тут 13674855 есть же мой вывод о целесообразности деревьев на одном поле parent_id... в конце поста. Перечитайте, сделайте отдельную табличку всех ребер и не мучайтесь. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2013, 07:19:42 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
javajdbc, спасибо за участие в обсуждении! javajdbclabirint, Работа с переменными -- дело непростое.... сама база под этим делом неустойчивая Алтернатива -- сделайте на кленте. Как? Что это подразумевает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2013, 09:09:43 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Arhat109labirint, Просмотрел фак ещё раз. Вот тут 13674855 есть же мой вывод о целесообразности деревьев на одном поле parent_id... в конце поста. Перечитайте, сделайте отдельную табличку всех ребер и не мучайтесь. :) ОК. ФАК перечитываю, если б он был на бумаге - уже до дыр бы зачитал, но "я не чайник - я только учусь"... Можно (не)много подробнее про таблицу всех ребер? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2013, 09:13:15 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirint, обыкновенная таблица связи узла с узлом: "родитель" - "потомок" - "порядок"(если надо) - "уровень"(если надо). Всё. Каждый новый потомок добавляется ко всем своим родителям сразу (добавляем все ребра к этому потомку для всех уровней дерева) , что позволяет простым условием "где родитель равен заданному" вытащить всех его потомков и даже рассортировать по уровням и/или по порядку, если дерево - ориентированно. Позволяет поддерживать практически любые графы, а не только деревья. В общем случае, размер таблицы растет как факториал от числа узлов, но для деревьев, особенно сильно ветвистых (много потомков) и не сильно глубоких (мало подуровней) - может оказаться также компактно как и поля "уровень" и "родитель" в основной таблице (уровень, порядок узла - полезны сами по себе и для других задач). ... а главное, если снабдить родителя и потомка доп. данными о сущностях - можно организовывать в деревья произвольные данные из разных таблиц/сущностей... :) Как пример: узел 1 - корень. Добавляем к нему потомков 2,3: появляются записи 1-2 и 1-3. Добавляем к узлу 2 потомков 4,5 (третий уровень поддерева): появляются записи: 1-4, 2-4 и 1-5, 2-5 Добавляем записи к узлу 5 (узлы 10,12,15): появляются записи 1-10,1-12,1-15 и 2-10, 2-12, 2-15 и 5-10, 5-12, 5-15. ... то есть добавляем новый узел ко всем родительским вершинам заданного узла (select где заданный = потомку). можно ваще оформить как отдельную таблицу с классом доступа на клиенте или ХП и гонять деревья независимо от их участников (собственно у себя так и сделал года 2 назад). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2013, 10:46:30 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
labirint, странно вы его перечитываете. Вот же 13969570 практически полный пример внутренней части процедуры тестирования, которой всё это гонял когда-то. Там и создание таблички, и её наполнение (есть даже вариант псевдослучайного построения деревьев за комментом)... есть и все тестируемые запросы... "Пгобовали"? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2013, 10:54:10 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Arhat109labirint, странно вы его перечитываете. Вот же 13969570 практически полный пример внутренней части процедуры тестирования, которой всё это гонял когда-то. Там и создание таблички, и её наполнение (есть даже вариант псевдослучайного построения деревьев за комментом)... есть и все тестируемые запросы... "Пгобовали"? :) Ну, так именно этот пример я и пробовал. Ничего не получилось :( При попытке заполнения таблицы Мускуль ругается на каждую строку ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2013, 11:24:38 |
|
||
|
запрос теоретически возможен?
|
|||
|---|---|---|---|
|
#18+
Arhat109, да, по поводу " таблица связи узла с узлом: "родитель" - "потомок" " со всеми вышестоящими - дело нешуточное. Если в структуре уровней 200-250..... Хотя для моего случая - допустимо, у меня примерно до 12 уровней дойдет. Чтобы закрепить понимание: для узла на 10-м уровне в таблицу ребер добавляется 9 строк? Начиная с 1-го узла . Правильно? А чтобы получить для него все верхние узлы, делаем запрос по родителям для непосредственного родителя? И прибавляем этого сАмого родителя. Да? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2013, 11:34:12 |
|
||
|
|

start [/forum/topic.php?fid=47&msg=38087086&tid=1834649]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
47ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
67ms |
get tp. blocked users: |
1ms |
| others: | 203ms |
| total: | 358ms |

| 0 / 0 |
