Конференция "Базы" » ссылка таблицы самц на себя [D7, IB6.x]
 
  • foriegn keys (19.12.08 08:22) [0]
    Всем доброго времени суток!

    есть таблица c иерархией (id integer, parent integer)
    как мне добавить внешний ключ:
    ALTER TABLE DETAIL ADD CONSTRAINT FK_DETAIL FOREIGN KEY (PARENT)
                 REFERENCES DETAIL (ID) ON DELETE CASCADE ON UPDATE CASCADE;

    так, чтобы я мог вставить потом корневой узел?
    ...
    Т.е. вопрос в том, как мне вставить корневой узел?
  • Сергей М. © (19.12.08 08:35) [1]
    Например, со ссылкой в PARENT на свой же ID
  • foriegn keys (19.12.08 09:02) [2]

    > Сергей М. ©   (19.12.08 08:35) [1]

    а как тогда оформить процедурку получения детей?
  • Сергей М. © (19.12.08 10:07) [3]
    Добавь в таблицу поле LEVEL, формируй его в триггерах - для корней оно пусть будет = 0

    Тогда

    select *
    from MyTree
    where PARENT = SomeRootNodeID and LEVEL > 0
  • Ega23 © (19.12.08 10:14) [4]
    select *
    from MyTree
    where PARENT = SomeRootNodeID and LEVEL > 0



    И что это даст? Нафиг эта проверка? Все, у кого парент = SomeRootNodeID, все будут иметь одно и тоже значение Level. Собственно, Parent.Level + 1

    Выборку значений я бы через хп организовал с рекурсивным вызовом.
  • foriegn keys (19.12.08 10:18) [5]

    > Сергей М. ©   (19.12.08 10:07) [3]

    не нра мне level: када апдейтить его буду, эт каким же триггер должон быть?
    и вообще: нихачу структуру БД приносить в жертву эээ.... чему? своему неумению?
    Как бы сделали Вы?
  • foriegn keys (19.12.08 10:19) [6]

    > Ega23 ©   (19.12.08 10:14) [4]

    так и делаю
  • Ega23 © (19.12.08 10:23) [7]

    > не нра мне level: када апдейтить его буду, эт каким же триггер
    > должон быть?

    Есть inserted, в нём есть ParentID. У Parent'а есть свой Level. Значит Level вставляемого будет Parent.Level + 1
    только мне непонятно нафиг тут вообще Level.
  • Сергей М. © (19.12.08 10:24) [8]

    > что это даст


    Это даст выборку всех узлов, дочерних по отношению к корню с ID равным интересующему автора (SomeRootNodeID)


    > Все, у кого парент = SomeRootNodeID, все будут иметь одно
    > и тоже значение Level. Собственно, Parent.Level + 1
    >


    Все верно. Это и подразумеваются.


    > с рекурсивным вызовом.
    >


    За каким тут рекурсия ?

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

    Доп.проверка на LEVEL > 0 нужна для исключения из выборки собственно корня, для которого согласно [1] условие PARENT = SomeRootNodeID окажется истинным.
  • Сергей М. © (19.12.08 10:28) [9]

    > не нра мне level


    Не не нра знач не нра.
    Наше дело предложить - ваше отказаться.


    > када апдейтить его буду


    При любом апдейте PARENT-поля этой записи.
    Ничего сложного.


    > эт каким же триггер должон быть?


    Пара доп.строчек добавляется - вот и все)


    > Как бы сделали Вы?


    Именно так я и сделал в некоторых своих вполне успешно работающих проектах.
  • Сергей М. © (19.12.08 10:30) [10]

    > не нра мне level
    >
    >


    А мне вот не нра null в PARENT у корневых узлов.
    На вкус и цвет, как говорится, ....)
    Хочешь - ешь, не хочешь - не ешь)
  • foriegn keys (19.12.08 10:31) [11]

    > Сергей М. ©   (19.12.08 10:24) [8]

    да не, автора волнует все дети...


    > Ega23 ©   (19.12.08 10:23) [7]


    > Есть inserted, в нём есть ParentID. У Parent'а есть свой
    > Level. Значит Level вставляемого будет Parent.Level + 1

    если будет не вставка, а редактирование уровня, то все немного усложнится, не так ли?

    Ну да ладно, level я все равно не использую.
  • Сергей М. © (19.12.08 10:39) [12]

    > автора волнует все дети


    Ну тогда да, рекурсия нужна.

    Но "все" - это ведь не дети, согласись ? Среди всех есть и внуки, и правнуки, и пра-пра-пра ..

    Так что на будущее изволь уж быть точнее в формулировках)
  • foriegn keys (19.12.08 10:39) [13]

    > Сергей М. ©   (19.12.08 10:39) [12]

    ок, просто думал, что это подразумевается
  • Сергей М. © (19.12.08 10:42) [14]

    > foriegn keys   (19.12.08 10:31) [11]


    Зато имея LEVEL и еще одну вспомог.таблицу можно обойтись без рекурсии, что дает ощутимый выигрыш в производительности при выборках такого рода на большущих деревьях.
  • Сергей М. © (19.12.08 10:43) [15]

    > foriegn keys   (19.12.08 10:39) [13]


    > это подразумевается


    Увы и отнюдь)
  • Ega23 © (19.12.08 10:44) [16]

    > Это даст выборку всех узлов, дочерних по отношению к корню
    > с ID равным интересующему автора (SomeRootNodeID)
    >


    Create table Test (
     id int,
     pid int,
     aName varchar(32),
     Level int,
     constraint pk_test primary key (id),
     constraint fk_test foreign key  (pid) references Test (id)
    );

    insert into Test (id, pid, aName, level) Values (0, null, 'Root', 0);
    insert into Test (id, pid, aName, level) Values (1, 0, 'Level1 Node1', 1);
    insert into Test (id, pid, aName, level) Values (2, 0, 'Level1 Node2', 1);
    insert into Test (id, pid, aName, level) Values (3, 0, 'Level1 Node3', 1);
    insert into Test (id, pid, aName, level) Values (4, 1, 'Level2 Node1-1', 2);
    insert into Test (id, pid, aName, level) Values (5, 1, 'Level2 Node1-2', 2);
    insert into Test (id, pid, aName, level) Values (6, 1, 'Level2 Node1-3', 2);



    Объясни мне смысл дополнительной проверки на Level в случае, когда я выбираю прямых "потомков" конкретного узла.
  • Ega23 © (19.12.08 10:45) [17]

    > Зато имея LEVEL и еще одну вспомог.таблицу можно обойтись
    > без рекурсии, что дает ощутимый выигрыш в производительности
    > при выборках такого рода на большущих деревьях.


    Это от кучи нюансов зависит. Может быть и даст. А может и не даст.
  • Сергей М. © (19.12.08 10:45) [18]

    > Ega23 ©   (19.12.08 10:44) [16]


    см. [10]
  • Сергей М. © (19.12.08 10:47) [19]

    > Ega23 ©   (19.12.08 10:45) [17]


    Тебе видней)
 
Конференция "Базы" » ссылка таблицы самц на себя [D7, IB6.x]
Есть новые Нет новых   [134477   +39][b:0][p:0.001]