За последние 24 часа нас посетили 30938 программистов и 1446 роботов. Сейчас ищут 875 программистов ...

"Деревья" без премудростей (в одном удобном запросе mysql)

Тема в разделе "MySQL", создана пользователем Mark32, 12 ноя 2014.

  1. Mark32

    Mark32 Активный пользователь

    С нами с:
    15 июн 2008
    Сообщения:
    539
    Симпатии:
    2
    Появился ли способ вывода из мускула иерархических данных? Типа id | name | parent_id ?
    По сути вложенные множества задача обычная, не сложная, но почему-то разработчики игнорят сделать наконец-то простой и удобный вывод "дерева" через один запрос, чтобы не пришлось выкручиваться всякими дополнительными функциями для разбора типа

    Код (PHP):
    1. function array_to_tree(array $array, $parent_id = 0)
    2. {
    3.     $array = array_combine(array_column ($array, 'id'), array_values($array));
    4.  
    5.     foreach ($array as $k => &$v) {
    6.         if (isset($array[$v['parent_id']])) {
    7.             $array[$v['parent_id']]['children'][$k] = &$v;
    8.         }
    9.         unset($v);
    10.     }
    11.  
    12.     return array_filter($array, function($v) use ($parent_id) {
    13.         return $v['parent_id'] == $parent_id;
    14.     });
    15. }
    Добавлено спустя 12 минут 40 секунд:
    На сайте explainextended(точка)com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/ приводится интересный пример такого запроса, ко всему прочему прибавляется колонка level, зачем думаю будет понятно из запроса:

    Код (Text):
    1. SELECT  CONCAT(REPEAT('    ', level - 1), CAST(id AS CHAR)),
    2.         parent,
    3.         level
    4. FROM    (
    5.         SELECT  id, parent, IF(ancestry, @cl := @cl + 1, level + @cl) AS level
    6.         FROM    (
    7.                 SELECT  TRUE AS ancestry, _id AS id, parent, level
    8.                 FROM    (
    9.                         SELECT  @r AS _id,
    10.                                 (
    11.                                 SELECT  @r := parent
    12.                                 FROM    t_hierarchy
    13.                                 WHERE   id = _id
    14.                                 ) AS parent,
    15.                                 @l := @l + 1 AS level
    16.                         FROM    (
    17.                                 SELECT  @r := 1218,
    18.                                         @l := 0,
    19.                                         @cl := 0
    20.                                 ) vars,
    21.                                 t_hierarchy h
    22.                         WHERE   @r <> 0
    23.                         ORDER BY
    24.                                 level DESC
    25.                         ) qi
    26.                 UNION ALL
    27.                 SELECT  FALSE, hi.id, parent, level
    28.                 FROM    (
    29.                         SELECT  hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
    30.                         FROM    (
    31.                                 SELECT  @start_with := 1218,
    32.                                         @id := @start_with,
    33.                                         @level := 0
    34.                                 ) vars, t_hierarchy
    35.                         WHERE   @id IS NOT NULL
    36.                         ) ho
    37.                 JOIN    t_hierarchy hi
    38.                 ON      hi.id = ho.id
    39.                 ) q
    40.         ) q2
    Давайте обсудим это, кому интересно! Есть ли конструкции поадекватнее? Кажется только в mysql не реализована понятная и простая возможность вывода деревьев..
     
  2. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    nested sets
     
  3. Mark32

    Mark32 Активный пользователь

    С нами с:
    15 июн 2008
    Сообщения:
    539
    Симпатии:
    2
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    не намного проще в итоге...
     
  4. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
  5. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    Код (Text):
    1. select * from tree order by left_key
    ну хер знает куда вам еще проще... в форум для блондинок?
     
  6. Mark32

    Mark32 Активный пользователь

    С нами с:
    15 июн 2008
    Сообщения:
    539
    Симпатии:
    2
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    artoodetoo привёл отличную табличку "многострадальных схем".

    Adjacency List - самый логичный и красивый вариант, остаётся только "изменить" исполнение "Hard" на "Easy" у Query Subtree. Это тема для обсуждения, быть может что-то придумали новое. К примеру,
    Код (Text):
    1.  
    2. SELECT  LPAD(' ', level * 4, ' ') || id, parent, level
    3. FROM    t_hierarchy
    4. START WITH
    5.         parent = 0
    6. CONNECT BY
    7.         parent = PRIOR id
    очень просто в Oracle, не так ли?

    START WITH определяет root дерева, и CONNECT BY связывает родителя с потомками.

    Не хочется верить что в Mysql так и не решен вопрос, быть может есть вариант потому и спрашиваю, чтобы не менять кардинально схемы на "чистое зло" типа нестед сетс. Моё мнение. Не поддерживаете точку зрения, не надо, хотелось бы обсудить с теми, кто придерживается подобного взгляда.
     
  7. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    artoodetoo, неплохая презентация. но надо субъективно тестировать в разных вариантах применения.
     
  8. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    Mark32, одного нежелания верить недостаточно :) в mysql нет встроеных типов для хранения деревьев. поэтому изучай полезные практики. пример с переменными любопытный и только. запрос очень тяжелый.

    Ganzal, конечно! инструмент подбирается под задачу. если изменения происходят редко, NS будут отличным вариантом.
     
  9. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    вот именно. да там каждый пук приводит к обновлению либо всех ключей справа от элемента либо вообще почти всех ключей. но если в задаче не очень часто обновляются данные то дальше уже перфоманс 8-байтного индекса будет поболе чем на реализации PE и не нужно лишних таблиц как в CT. для таких популярных задач как каталоги товаров или списки форумов вполне хватит и NS.
     
  10. Mark32

    Mark32 Активный пользователь

    С нами с:
    15 июн 2008
    Сообщения:
    539
    Симпатии:
    2
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    это да. как пример привёл...

    Для NS принципиально нужна InnoDB ?
    Можете посоветовать хорошую библиотеку (или просто методы) NS для тестирования?
     
  11. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    нет
    нет

    тестирование? скажи прямо: "дайте готовое решение". ответ: ищи, их миллион.
     
  12. Mark32

    Mark32 Активный пользователь

    С нами с:
    15 июн 2008
    Сообщения:
    539
    Симпатии:
    2
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    да, а ещё жену одолжи на часик..!
     
  13. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    это пожалуйста. но деньги вперед.
     
  14. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    В mysql много что не решено, хехе. Используйте нормальные субд, если так хочется рекурсивные запросы.
     
  15. Mark32

    Mark32 Активный пользователь

    С нами с:
    15 июн 2008
    Сообщения:
    539
    Симпатии:
    2
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    "Не хочется верить" это в том смысле, что "допилить" можно в принципе всё что угодно, была бы "муза")) А от мускула никуда я не уйду, люблю его братку))

    Кстати есть вариант с Adjacency List без рекурсии (в запросе само собой, даже без рекурсии в методе php))))
     
  16. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Re: "Деревья" без премудростей (в одном удобном запросе mysq

    или "её сестренку"... ходят слухи что приставка май - имя дочери одного из разработчиков субд.