AXForum  
Вернуться   AXForum > Прочие обсуждения > forum.mazzy.ru > Обсуждение статей на mazzy.ru
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 26.09.2004, 14:23   #61  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
в том то и дело, что нужно будет.

Скорее всего, такую иерархию введет организация, которая занимается строительно-монтажными работами.
Причем наверняка эта огранизация занимается разными видами строительно-монтажных работ.

Так вот "Для наружных работ", "Для мебели", "Для ремонта" - это виды деятельности. И очень типично, что виды деятельности компании замешиваются куда-то в середину иерархии. По-крайней мере, это очень типично для тех? с кем я работал.

Да, есть 5% случаев - это сам производитель лаков и красок
Но в остальных 95% случаев виды деятельности будут в середине иерархии. Хоть так, хоть иначе.
__________________
полезное на axForum, github, vk, coub.
Старый 26.09.2004, 14:30   #63  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Цитата:
Сообщение от mazzy
Цитата:
Сказано. Правда во второй части.

Пример - спецификации (BOM).
Узлы состоят из материалов и других узлов.

Спецификации - типичная иерархия.
Причем именно иерархия, а не граф. С циклами в спецификациях в обязательном порядке приходится бороться.

Причем спецификациям изначально присуща рекурсия.
Рекурся содержится в определении.
Причем именно бесконечная рекурсия.

Так что не любую иерархию можно описать несвязанными полями.
Просто в БОЛЬШИНСТВЕ случаев иерархию применяют совершенно неоправдано.

Еще раз спасибо за высказывания.
По большей части - с вами совершенно согласен.
Наверное невнимательно читал.
Действительно BOM - живейший пример "нормализованных" деревьев в Аксапте - а я про них как то и не вспомнил даже.
Старый 26.09.2004, 14:43   #64  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Цитата:
Сообщение от mazzy
в том то и дело, что нужно будет.

Скорее всего, такую иерархию введет организация, которая занимается строительно-монтажными работами.
Причем наверняка эта огранизация занимается разными видами строительно-монтажных работ.

Так вот "Для наружных работ", "Для мебели", "Для ремонта" - это виды деятельности. И очень типично, что виды деятельности компании замешиваются куда-то в середину иерархии. По-крайней мере, это очень типично для тех? с кем я работал.

Да, есть 5% случаев - это сам производитель лаков и красок
Но в остальных 95% случаев виды деятельности будут в середине иерархии. Хоть так, хоть иначе.
Мы - торговый центр. У нас действительно много других товарных групп для которых признак "внутри/снаружи дома/чеголибо" совершенно не нужен.

Мебель \ ...
Бытовая техника \ ...
Бытовая химия \ ...
и т.д.

Да это мне кажется уже неважно - суть вопроса ведь ясна. Для нас "видом деятельности" скорее являются признаки сезонности товара и тому подобного - вот их мы делаем отдельными полями таблицы, не более того. Классификатор старались сделать как можно более "ассортиментным", но не я его делал, да и в то время когда он составлялся я был далёк мыслями от этой темы. Сейчас просматривая наш классификатор я нахожу его процентов на 10-20 ненормализованным.
Старый 27.09.2004, 11:19   #65  
Valery is offline
Valery
Участник
 
381 / 10 (1) +
Регистрация: 28.02.2002
Адрес: Москва
Ещё одна интересная ссылка по теме
http://www.sql.ru/articles/mssql/010...eesInSQL.shtml
Старый 27.09.2004, 12:55   #66  
Dzemon is offline
Dzemon
Moderator
 
1,247 / 12 (3) ++
Регистрация: 09.09.2004
Спасибо =A=L=X= за развернутый трактат о методике построения деревьев.
Небольшое замечание по поводу ненормализованного лакокрасочного дерева.
Идеальный (нормализованный) иерархический классификатор должен содержать набор множеств (корневых) с непересекающимися подмножествами. В случае ненормализованной иерархии возникают пересекающиеся множества, а это уже т.н. R-деревья. Вам это ничего не напоминает? Я имею ввиду геоинформационные системы. А это ведь одни из наиболее сложных и ресурсоемких систем и не только в плане объема информации.
Я хочу сказать, что сложность системы должна соответствовать решаемым задачам. Структуру классификатора надо по возможности максимально упрощать. Возможно даже разбить на несколько отдельных деревьев или делать комбинированную форму с грубой фильтрацией поверх древовидного классификатора.
Старый 27.09.2004, 15:52   #67  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Цитата:
Сообщение от Valery
Ещё одна интересная ссылка по теме
http://www.sql.ru/articles/mssql/010...eesInSQL.shtml
Очень интересный подход
Правда прямо не говорится про недостатки (по сравнению с тем же id/parentId подходом):
- вставление нового элемента превращается в апдейт в среднем половины записей в базе (против 1 insert-а в случае id/parentId подходе)
- алгоритм нахождения непосредственных детей или непосредственного родителя (т.е. только с одного уровня) становится нетривиальной задачей (против 1-ого простого select-а в id/parentId)
- алгоритм переноса группы из одного места в другое становится нетривиальной задачей (против 1-ого update-а в id/parentId подходе).
выигрыш (правда существенный) имеется только при выборках данных и удалении ветки (где классический подход лажает по полной).
Мне на ум приходило некое, компромиссное между этими двумя вариантами, решение - поддерживать избыточную таблицу id / parentId / distance - где хранятся связи между каждым родителем и его детьми, для любого уровня вложенности (distance = 0, если родитель является непостредственным родителем, =1 если через одного и т.д.)
В этом случае вставка выполняется за 2 insert-а, выборка всех детей/родителей (как произвольной вложенности, так и до заданного уровня вложенности) - за 1 select, перемещение из группы в группу - нетривиальной задачей, удаление - за 2 delete.

Но как ни крути - в рамках реляционных баз деревья - это гимор. По моему при любой организации таких структур всегда какая то из операций над ними будет "нетривиальной". Тут надо исходить из того какие из операций будут выполняться реже других
Старый 27.09.2004, 15:54   #68  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Цитата:
Сообщение от Dzemon
...а это уже т.н. R-деревья. Вам это ничего не напоминает?..
Я имею ввиду геоинформационные системы....

Я хочу сказать, что сложность системы должна соответствовать решаемым задачам. Структуру классификатора надо по возможности максимально упрощать. Возможно даже разбить на несколько отдельных деревьев или делать комбинированную форму с грубой фильтрацией поверх древовидного классификатора.
Согласен с тем что вы хотите сказать, вот только с R-деревьями (или с таким термином, хотя аналогия с геоинформационными системами мне ничего не сказала) не знаком.
Старый 27.09.2004, 16:35   #69  
Dzemon is offline
Dzemon
Moderator
 
1,247 / 12 (3) ++
Регистрация: 09.09.2004
Цитата:
Сообщение от =A=L=X=
Согласен с тем что вы хотите сказать, вот только с R-деревьями (или с таким термином, хотя аналогия с геоинформационными системами мне ничего не сказала) не знаком.
http://www.math.dcn-asu.ru/learning/comput...ection5_15.html
Старый 28.09.2004, 12:22   #70  
Andrew_Lan is offline
Andrew_Lan
Участник
 
4 / 10 (1) +
Регистрация: 23.09.2004
Цитата:
Сообщение от Valery
Ещё одна интересная ссылка по теме...
И ещё одна ссылка:
http://rdbms.narod.ru/article/tree/index.html

Правда, при ссылке на Joe Celko они, по-моему, допустили ошибку. Кстати, одного из авторов предлагаемого подхода знаю лично .
Старый 10.10.2004, 23:07   #71  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Опубликовал заключительную часть статьи.
Иерархический справочник и Axapta. Часть 3: Проект

К сожалению, абсолютно не хватает времени, чтобы оформить результаты так, как хотелось бы. Поэтому выложил статью и проект в настоящем виде. Когда будет время, обязательно вернусь к этой теме.

Отдельно и обязательно хотелось бы отметить, что в проекте нет ни строчки кода. Все объекты создавались при помощи drag'n'drop. Используются только возможности ядра.
Вложения
Тип файла: xpo ma_Hierarchy.xpo (226.6 Кб, 539 просмотров)
__________________
полезное на axForum, github, vk, coub.
Старый 12.10.2004, 16:52   #72  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Возражение против тезиса о том что классификаторы вида id/parentId непомерно тяжеловесны в запросах.

Предположим имеем таблицы:

Classif ( id, parentId, level ) // избыточное поле level отнюдь не будет лишним
Item ( id, name, ClassifId, ... )

Предполагаемая программа, легко справляющаяся с рекурсией такого классификатора одним запросом должна обладать одним свойством - возможностью делать "динамические запросы". Стараюсь придерживатсья синтаксиса Аксапты, хотя с нарушениями для краткости изложения.
Логика универсального запроса, выворачивающего всю структуру таблицы вместе с подчинениями не так уж и сложна на самом деле:

Шаг 1:

<div class='XPPtop'>X++</div><div class='XPP'>[color=:blue]int[/color] n = ([color=:blue]select[/color] max( level ) [color=:blue]from[/color] Classif).level;</div>

Шаг 2:

<div class='XPPtop'>X++</div><div class='XPP'>
Classif c[ n ];
Item i[ n ];

[color=:blue]select[/color] c[ 1 ] [color=:blue]where[/color] c[ 1 ].ParentId [color=:blue]==[/color] [color=:red]""[/color] [color=:blue]outer[/color] join i[ 1 ] [color=:blue]where[/color] i[ 1 ].ClassifId [color=:blue]==[/color] c[ 1 ].Id
[color=:blue]outer[/color] join c[ 2 ] [color=:blue]where[/color] c[ 2 ].ParentId [color=:blue]==[/color] c[ 1 ].Id [color=:blue]outer[/color] join i[ 2 ] [color=:blue]where[/color] i[ 2 ].ClassifId [color=:blue]==[/color] c[ 2 ].Id
[color=:blue]outer[/color] join c[ 3 ] [color=:blue]where[/color] c[ 3 ].ParentId [color=:blue]==[/color] c[ 2 ].Id [color=:blue]outer[/color] join i[ 3 ] [color=:blue]where[/color] i[ 3 ].ClassifId [color=:blue]==[/color] c[ 3 ].Id
...
[color=:blue]outer[/color] join c[ n ] [color=:blue]where[/color] c[ n ].ParentId [color=:blue]==[/color] c[ n - 1 ].Id [color=:blue]outer[/color] join i[ n ] [color=:blue]where[/color] i[ n ].ClassifId [color=:blue]==[/color] c[ n ].Id</div>

Думаю и итоги можно отбирать спокойно подобным образом, сейчас просто нет времени думать над этим.
Вопрос теперь в том может ли аксапта быть столь динамичной?
Если нет - то можно ведь просто ограничить максимальный уровень вложенности групп классификатора.
Старый 12.10.2004, 17:36   #73  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Хехе... А ведь таким образом можно выполнять практически любые задачи, связанные с обработкой и траверсированием древовидных структур:

Получение всех родителей текущего элемента дерева:

<div class='XPPtop'>X++</div><div class='XPP'>Classif cur;
...
[color=:blue]int[/color] n = cur.level;
...
Classif parent[ n - 1 ];

[color=:blue]select[/color] parent[ 1 ] [color=:blue]where[/color] parent[ 1 ].Id [color=:blue]==[/color] cur.ParentId
join parent[ 2 ] [color=:blue]where[/color] parent[ 2 ].Id [color=:blue]==[/color] parent[ 1 ].ParentId
...
join parent[ n - 1 ] [color=:blue]where[/color] parent[ n - 1 ].Id [color=:blue]==[/color] parent[ n - 2 ].ParentId;</div>

Получение всех детей текущего элемента получается модификацией фрагмента из поста выше, а именно:

<div class='XPPtop'>X++</div><div class='XPP'>[color=:blue]int[/color] n = ([color=:blue]select[/color] max( level ) [color=:blue]from[/color] Classif).level - cur.level;

Classif c[ n ];

[color=:blue]select[/color] c[ 1 ] [color=:blue]where[/color] c[ 1 ].ParentId [color=:blue]==[/color] cur.Id
[color=:blue]outer[/color] join c[ 2 ] [color=:blue]where[/color] c[ 2 ].ParentId [color=:blue]==[/color] c[ 1 ].Id
...
[color=:blue]outer[/color] join c[ n ] [color=:blue]where[/color] c[ n ].ParentId [color=:blue]==[/color] c[ n - 1 ].Id</div>

Полная выборка элементов с подэлементами уже описана.
Ну и т.д....
Старый 12.10.2004, 21:09   #74  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от =A=L=X=
Думаю и итоги можно отбирать спокойно подобным образом, сейчас просто нет времени думать над этим.
Вопрос теперь в том может ли аксапта быть столь динамичной?
А это надо?
Прежде чем трясти стоит таки немножко подумать, поэкспериментировать...

Как по вашему, =A=L=X=, каков план построит SQL для такого запроса?
Является ли план оптимальным?
Как вы думаете как будет SQL сервер выполнять n внешних соединений?
Можно ли ваш запрос сделать таким образом, чтобы он выполнялся оптимально?

И только после ответа на эти вопросы можно вернутся к вашему - должна ли Аксапта делать такие запросы

Поэкспериментируйте - напишите статические запросы подобного вида. Посмотрите на план...
__________________
полезное на axForum, github, vk, coub.
Старый 12.10.2004, 21:41   #75  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 645 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
Почитал... Интересно...

В целом, Ваша проблема, ИМХО, в том, что Вы ищете какой-то идеальный вариант. Конечно, mazzy здесь народ спровоцировал, назвав свой метод безапелляционно правильным.

На самом деле, все зависит от конкретной задачи. В этом отношении мне наиболее ценным из всех статей показался следующий пассаж:
Цитата:
Просто постановщики задач, как правило не хотят думать на эту тему, а просто заставляют программистов делать универсальные деревья. Плохим постановщикам так проще жить!
А под конкретные задачи может и связка по ID-ParentID быть лучшим решением. В общем, гибче надо быть.

P.S.: Кстати, из всех ссылок наиболее полезной мне кажется ссылка Lexey (http://rsdn.ru/?article/db/Hierarchy.xml). В этой статье действительно дан обзор различных подходов и некоторое (конечно, поверхностное, но для обзора больше и не надо) их сравнение.
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
Старый 12.10.2004, 21:50   #76  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 645 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
Что касается "нормализованных" деревьев (вообще-то, этот термин используется для других целей): сомневаюсь, что оно действительно Вам поможет. Что касается технологии: про R-деревья книжки написаны, так что проблемы и подходы к их решению известны. Вы рассматриваете этот вопрос с точки зрения психологии пользователей. Мне кажется, здесь все-таки ситуация тяжелее. И "ненормализованное дерево" может оказаться приемлемым (как вариант, на AxForum'е изначально были разделы Axapta и Navision, в каждом из которых были подразделы Функционал, Программирование и Прочее, но никто не жаловался ). С другой стороны, не факт, что при "нормализации" дерева Вы получите приемлемый для всех пользователей результат.
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
Старый 13.10.2004, 08:11   #77  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Цитата:
А это надо?
Прежде чем трясти стоит таки немножко подумать, поэкспериментировать...

Как по вашему, =A=L=X=, каков план построит SQL для такого запроса?
Является ли план оптимальным?
Как вы думаете как будет SQL сервер выполнять n внешних соединений?
Можно ли ваш запрос сделать таким образом, чтобы он выполнялся оптимально?
Если приглядеться чуть чуть то очевидно что предлагаемый запрос почти аналогичен следующему:

select countries
outer join cities where cities.countryId == countries.Id
outer join streets where streets.cityId == cityId
...
(короче говоря ваш пример )
...особенно, если таблицу Classif проиндексировать по полю level - этим можно будет пользоваться для index hint-а, "разделяющего" города от улиц, а следовательно хороший построитель планов запросов поведет себя почти так же, как в вышеприведенном фрагменте.
Конечно выполнятся такой запрос будет несколько медленне чем в случае с разделенными таблицами - как раз затраты на то чтобы отсеивать записи по этому индексу, зато преимущества очевидны - гибкость и универсальность, немыслимая в случае разделенных таблиц, а оно того стоит, когда речь идет о "нормализованном" классификаторе.
(Времени проводить сравнительные тесты сейчас просто нет, но тема для меня интересна, возможно когда нибудь займусь этим.)
Особенно удобно становится работать с таблицей подобным образом, если ограничивать уровень вложенности справочников (совсем как в 1С) - все накладные расходы очевидны плюс исключается случай, когда из-за одной, очень глубокой ветки запрос на все остальные непомерно раздувается лишними полями в строках, хотя их уровень вложенности мал по сравнению с ней. (Кстати, загоняя поле level в фильтр датасоурсов для такого случая с ограниченной глубиной, мы можем выстраивать такие же формы с "межклассовыми иерархиями" как в вашем примере, почти без единой строчки кода)

Цитата:
И только после ответа на эти вопросы можно вернутся к вашему - должна ли Аксапта делать такие запросы
Не утверждаю что обязана, но утвержаю что нет в этих запросах ничего страшного.

Насчёт вашей последней статьи.

Мне собственно непонятно в чём её соль - ведь в ней рассмотрен тривиальный случай межклассовой иерархии отношения один-ко-многим, в коей завязаны 99% всех таблиц в Аксапте и которой в общем то все просто обязаны уметь пользоваться. Отношения между странами-городами-улицами это просто классика жанра реляционных БД.
Тут видимо предлагается иерархии упорядочивать таким образом - разбивая их на набор взаимосвязанных таблиц. Действительно многие вещи можно уложить в такую схему (та же ассортиментная классификая товаров вполне может быть разбита на несколько таблиц по уровням классификации). Правда кроме преимуществ простоты подхода недостатков КУЧА:
- Жесткая привязка к определенной глубине иерархии - добавление новых уровней превращается в головняки программисту + сопутствующие проблемы
- Неоднородность построения запросов, а следовательно неоднородность кода, работающего с универсальным представлением дерева в TreeView
- Трудности с привязыванием подчиненных классификатору таблиц к разным его уровням
- Невозможность/чрезвычайная затрудненность переноса элементов с уровня на уровень
и т.д.
(вообще в идеале подход id/ParentId, level может обеспечить приличную универсальность, а если в системе есть возможность строить динамические запросы по вышеобозначенной схеме, то и нормальную производительность, сравнимую с разделением таблиц, особенно при ограниченном уровне вложенности)
...
И самое главное - если вы реализовали такой подход и не испытали ни одной из вышеперечисленных трудностей, то значит... вы имеете дело с простыми межклассовыми иерархиями отношений один-ко-многим, так что не морочьте мне голову и не пишите гневных опровержений не по адресу.
Старый 13.10.2004, 09:15   #78  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от =A=L=X=
Если приглядеться чуть чуть то очевидно что предлагаемый запрос почти аналогичен следующему:

select countries
outer join cities where cities.countryId == countries.Id
outer join streets where streets.cityId == cityId
...
(короче говоря ваш пример )
Не-а.
В вашем примере используется одна таблица.
Большая. С одним индексом и статистистикой на всех

Здесь используется несколько таблиц.
С разными индексами. И статистиками.

Хотя над вашими словами безусловно стоит подумать. Спасибо.
__________________
полезное на axForum, github, vk, coub.
Старый 02.01.2005, 20:52   #79  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
О реализации дерева в Навижине
http://navisioner.com/html/treeview.htm
__________________
полезное на axForum, github, vk, coub.
Старый 10.01.2005, 17:01   #80  
igor165 is offline
igor165
Участник
 
1 / 10 (1) +
Регистрация: 10.01.2005
Данную серию статей корректней было бы назвать не "Иерархический справочник и Axapta", а "Иерархический справочник не для Axapta".

Создалось впечатление, что Автор подспудно ограничивается иерархиями, построенными по фасетному типу. Поэтому его доводы и выводы скорее относятся не Axapt-е, а к общим вопросам представления данных со структурой подобного рода. В оправдание Автора можно привести тот аргумент, что подобные структуры относительно просты в реализации и понимании и по этой причине чрезвычайно широко распространены.

Рассуждения типа "нужно использовать" или "можно использовать" фильтры на таблицы вместо treeview на системах с реляционной структурой конечно интересны.
Однако, хотелось бы, что бы Автор, рассмотрел тему с более общих методологических позиций вопросы иерархического представления данных в пользовательских интерфейсах. В этом случае его работа уже не будет восприниматься только как крик души Автора.
 


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 05:07.