C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Реализация множества подгрупп
full_lamer
Отправлено: 13.01.2005, 17:58


Машинист паровоза

Группа: Участник
Сообщений: 225



доброго времени
стоит следующая задача:
реализована таблица
id
name
isgroup -- true — если запись определитель группы
group_id -- в какую группу включена запись

необходимо отображать все надгруппы в которые входит элемент
например если элемент входит в группу 3, группа 3 в 5, группа 5 в 6: то список надгрупп должен иметь сл. вид: 6.5.3.

мои варианты:
0. на стороне клиента производить рассчет для каждого отдельного поля;
1. на стороне клиента производить рассчет для всей таблицы при ее первом вызове после изменения;
2. ввести в таблицу отдельное поле и прописать триггер;

у кого какие соображения?
спасибо.

зы. субд sql server и ib6
AVC
Отправлено: 14.01.2005, 09:18


Ветеран

Группа: Модератор
Сообщений: 1583



По моему мнению если есть возможность "озадачить" сервер, то грех её упускать. Клиент должен как можно меньше знать о внутренней кухне сервера.

Вариант реализации (на сервере) зависит от того насколько часто, как быстро и что конкретно вы хотите видеть.
Если строку вида "6,5,3" — это одно решение, если выборку с записями 6 / 5 / 3 — это другое ...

PS. Если у вас group_id это id другой строки этой же таблицы, то вы нарисовали самосвязную таблуцу, используемую для хранения "деревьев". Вас интересует обход дерева вверх. Можно поискать готовые решения конкретно под ваш сервер.
full_lamer
Отправлено: 14.01.2005, 15:08


Машинист паровоза

Группа: Участник
Сообщений: 225



доброго времени
2AVC
можно на "ты" если не трудно...
насчет реализации я представляю это в виде триггера на изменения, добавления и удаление данных.
обход деревьев — интересное предложение... а посоветовать (ничего что я на "ты") ресурс не можешь...? я просто не совсем предсталяю себе это таблицу...
AVC
Отправлено: 14.01.2005, 16:01


Ветеран

Группа: Модератор
Сообщений: 1583



И тебе того же.
Можно и на ты.
Не понял вопрос — таблица же уже есть или как?
Т.е. у нас есть допустим такие записи:
1, 'узел1', true, 0
2, 'узел2', true, 1
3, 'лист3', false, 2
и ты хочешь записать в дополнительные поля, допустим, для лист3 значение '2,1' ?
Если да, то это и есть обход вверх и этим действительно может заниматься триггер. Реализуется написанием реентерабельной sp и вызовом её из триггера.
Но это, как я писал, зависит от преследуемой цели — что будет делаться дальше с этим дополнительным полем. В виде простой строки в стандартном SQL оно малоэффективно.
full_lamer
Отправлено: 14.01.2005, 16:23


Машинист паровоза

Группа: Участник
Сообщений: 225



нет я просто пока пытаюсь пректированием заниматься... просто думаю как и что будет лучше сделать...
вообщем то присутствие специального поля по ИМХО может разгрузить сервер от лишей работы... и так просто будет удобнее хранить данные — тем более они очень редко изменяются...
а полная идея такая: знаешь что такое план счетов? каждый счет имеет определенное кол-во подсчетов и например счет 10 — (насколько я помню) поступление — а 10.9 поступление запастных частей... но я точно не помню... так вот при раскрытии такой вот таблицы высвечиваются толкьо счета (пока условно объясню на плане счетов) и около каждого счета стоит кнопка раскрытия(закрытия) группы и ид счета (10, 10.1, 10.1.1, 10.1.2, 10.2. и т.д.)... я просто соображаю как это сдалеть чтобы было просто и удобно для юзеров и программная часть очень была оптимальной...
AVC
Отправлено: 14.01.2005, 16:51


Ветеран

Группа: Модератор
Сообщений: 1583



Что такое план счетов знаю. Когда делал бухгалтерскую программу, то не мудрствуя лукаво сделал первичный ключ "счет" строковог типа, а все выборки делались при помощи like. Например Sum(Debet) where schet like ('361?') Group by Schet — показывает суммы дебетов операций счета 361 (расчеты с покупателями). + использовал три уровня аналитики. Из неудобств — со временем для единообразия пришлось снабдить таблицу альтернативным первичным ключем тип integer.
Т.е. идея — так как счета ни когда не меняют родителя сам номер счета содержит путь к нему.
full_lamer
Отправлено: 14.01.2005, 16:59


Машинист паровоза

Группа: Участник
Сообщений: 225



счета были в качестве распространненого и более понятного примера — на повестке дня оптимизировать таблицы экселя бизнес плана.. то есть есть огромный док екселя с огромным количеством позиций (1.1. ... 10.2.3 и тд) есть задание привести это к БД... а там позиции будут (не постоянно) но меняться... это конечно не так важно для органиции БД но для юзеров будет очень удобно (ИМХО)... как считаешь?
AVC
Отправлено: 14.01.2005, 17:35


Ветеран

Группа: Модератор
Сообщений: 1583



Первое, что приходит в голову -

Если работать с обычными Select'ами
дополнительное текстовое поле типа строка с конкатенацией узлов от верхнего с фиксированным числом знаков в каждой группе — поле нужно при показе для правильной сортировке. Заполнять триггером класса строка будет затруднительно так как изменение code в одной строке порождают необходимость изменения всей подветви. Долго и дорого.
Если использовать триггер класса таблица (если такой допустим) то это может упростить решение проблеммы.

Если запрос используется только для просмотра — то можно перелить выборку в TreeView. Там за счет алгоритма закачки сортировка будет правильной безо всяких дополительных полей. Но будут проблемы с редактированием.

В IB можно (?) написать SP, которая рекурсивно обошла бы дерево и вернула бы открытый курсор.

Можно сделать процедуру которая меняет значение code в нужной записи. Это очень напоминает тринггер, но имеет одно преимущество — последовательность действий. Сначала меняем поле, а затем пересчитываем дерево. (как в триггере класса таблица)

Может кто еще чего посоветует. smile.gif

А, да, можно сменить сервер. Oracle позволяет делать иерархические запросы простым Select'ом.
full_lamer
Отправлено: 14.01.2005, 17:51


Машинист паровоза

Группа: Участник
Сообщений: 225



сервер пока менять не хочу... потому что sql я коекак знаю... я сдача проекта уже скоро... а oracle я токо токо изучать начал (правда еще даже не поставил)...

QUOTE
В IB можно (?) написать SP, которая рекурсивно обошла бы дерево и вернула бы открытый курсор.

я писал рекурсивную для выборки — думаю что если вставить запрос на изменение то особо ничего страшного не будет...

QUOTE
Можно сделать процедуру которая меняет значение code в нужной записи.

так даже будет логичнее....

Вернуться в Работа с базами данных в C++Builder