[MSSQL] Клиент-Серверное приложение + Поиск родителя

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

[MSSQL] Клиент-Серверное приложение + Поиск родителя

Сообщение FireFenix » 19.04.2011 (Вт) 0:15

Обрисую ситуацию.

Имеется клиент-серверное приложение. Работаю над синхронизацией пользователей...
В клиентской части объекты представлены в виде древа и отображаются в TreeView, которые также представлены в базе в виде полей (id, id_type, id_parent, name)
Причём разные объекты находятся в разных древах, т.е. образуют различные цепочки деревьев в зависимости от типа
Хранятся объекты в .NET generic-словаре Dictionary(Of Integer, тип_объекта)
Аналогично храниться GUI-сущность в generic-словаре Dictionary(Of Integer, графический_тип)

Когда Клиент1 хочет добавить объект в некоторое древо с потомком id_parent, то для того чтобы внести Клиенту2 в нужные древа этот элемент, ему нужно перебрать рекурсией все деревья.

Вот ищу лёгкий путь такого взаимодействия... Обратился к CTE[msdn]
Использую CTE для нахождения родителя цепочки данного типа, если таковой использует Клиент2, то Клиент2 ищет ближнего родителя по Id и добавляет в древо данный объект

Т.е. использую запрос аналогичный
Код: Выделить всё
WITH Generation (Id) AS
(
    SELECT Id_Parent
    FROM dbo.Person
    WHERE Id = 6
UNION ALL
    SELECT Person.Id_Parent
    FROM Generation, Person
    WHERE Generation.ID=Person.ID
)
SELECT TOP 1 Person.ID, Person.Name, Person.Id_Parent
FROM Generation, dbo.Person
WHERE Generation.ID = Person.ID
ORDER BY Person.ID;
GO


Так вот, всё мучает вопрос производительности и элегантности...

* Вроде как перебор клиентом всех цепочек объектов - очень накладно, т.к. по идее сервер это должен сделать быстрее. Только вот при некотором количестве юзеров и количестве объектов в БД - данная процедура по идее будет убивать сервер только этой задачей.
* Была идея переложить поиск главного родителя на Клиент1, но тогда выходит громоздкая архитектура взаимодействия звеньев или нужно строить дополнительное древо (а так используется косвенное древо, которое строиться при загрузки цепочки и хранит граф. объекты)

Уже сколько думаю - ничего хорошего и быстрого не выходит. Хотелось бы услышать мысли или опыт проектирования подобных систем.
Пока что подумываю о переделки структуры взаимодействия в ущерб архитектуре, т.е. переложить всё на Клиент1, тем самым убрав заботу других участников и возможно уменьшив требуемые затраты.
Последний раз редактировалось FireFenix 02.05.2011 (Пн) 17:09, всего редактировалось 1 раз.
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

HandKot
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 283
Зарегистрирован: 28.06.2006 (Ср) 13:34
Откуда: Sergiev Posad

Re: [MSSQL] Клиент-Серверное приложение + Поиск родителя

Сообщение HandKot » 19.04.2011 (Вт) 8:01

что-то я не до конца понял.
приведите пример таблиц и что должно происходить (какие измененеия происходят в таблицах), "Когда Клиент1 хочет добавить объект в некоторое древо"
I Have Nine Lives You Have One Only
THINK!

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: [MSSQL] Клиент-Серверное приложение + Поиск родителя

Сообщение FireFenix » 20.04.2011 (Ср) 22:06

Имеются 5 типов объектов и для них отдельные таблицы
* Class (id, id_parent, name)
* Prototype (id, id_parent, name)
* Object (id, id_parent, name)
* Assembly (id, name)
* Item (id, name)

Item и Assembly связаны между собой и с Object через косвенную таблицу link (id, id_parent, id_parent_type, id_link, id_link_type)

Имеем связи

Class <- Class (id <- id_parent)
Class <- Prototype (id <- id_parent)
Prototype <- Object (id <- id_parent)
Object <- Assembly (через ссылки в таблице link)
Assembly <- Assembly (через ссылки в таблице link)
Assembly <- Item (через ссылки в таблице link)

В итоге по всем связям строиться дерево, но клиент может работать с различными уровнями древа и с разными ветвями, при этом одновременно открыв их в разных окнах.

К примеру Клиент1 добавляет Item (id = 155, name = "Вещь 155")
Сервер отсылает клиенту сигнал о синхронизации, что занесён новый элемент
Клиент2 посылает запрос выборки по id и получает объект и ссылку на него и его родителя в таблице link

Дальше Клиент2 должен определить, нужен ли ему этот объект, т.к. объект может входить в не открытую часть древа.
Тем самым клиент2 перебирает всё древо Assembly в поисках родителя, если таковой найден - добавляется child'ом объект
Потом перебираются графические древа в разных окнах, которые построены. И если какое-либо древо использует родителя, то объект добавляется

Выходит, что с ростом БД скорость полного перебора древа будет расти экспоненциально (перебор дерева в движке + поиск в ГУИ).
Для снижения пробега по древу, я додумал ещё получать первого родителя из ветки объекта, тем самым, ускорив поиск в GUI части, но вот не знаю как лучше насчёт производительности и элегантности...

Получилось что-то вроде:
Клиент1 (Создание нового элемента) -> Сервер (занесение в таблицу) -> Сервер (Сигнал синхронизации всем юзерам)
Клиент2 (Запрос по сигналу) -> Север (Выборка элемента, поиск "генеологического первого родича" по типу, выборка ссылки) -> Клиент2(Ответ)

Ещё были варианты
* Перенести поиск "генеологического первого родича" в клиент, но тогда будет плохое изменение архитектуры работы
* Выбирать не только "главного родича" но и всю ветку - возможно ещё бы ускорило поиску нужного элемента в движке, но вроде не выгодно по количеству данных и затратам
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 152

    TopList