powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Построение таблицы для древовидной структуры
9 сообщений из 9, страница 1 из 1
Построение таблицы для древовидной структуры
    #36109912
TechnoDreamer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть база данных такого вида:

CREATE TABLE InfoTree (
ID AUTOINCLARGEINT
ParentID LARGEINT DEFAULT -1 NOT NULL,
Name WIDESTRING(1023)
);

CREATE TABLE Tags (
TagID AUTOINCLARGEINT,
TagName WIDESTRING(1023)
);

CREATE TABLE TagDependancy (
TagID LARGEINT,
ID LARGEINT
);

Первая таблица содержит древовидную структуру данных (полей там побольше конечно, но в данном случае это не важно).
Вторая таблица содержит список возможных тэгов и их уникальных идентификаторов.
И третяя таблица содержит связи между записями главной таблицы и тэгами.

Проект написан на Delphi, используется база данных Absolute Database.
Для отображения используется компонент DevExpress TcxDBTreeList. Он автоматом отрисовывает дерево по таблице InfoTree на основе ID и ParentID.

Мне дали этот проект доработать, необходимо добавить еще один TcxDBTreeList который будет показывать дерево тегов.
Это дерево всегда двухуровневое. На первом уровне у него имена тэгов (Tags.TagName), на втором уровне имена элементов основной таблицы (InfoTree.Name) соответсвующие этому тэгу.
Т.е. нужно построить таблицу c тремя полями:
ID - уникальный идентификатор
ParentID - родитель, для записей первого уровня (тэгов), он будет равен -1
Name - имя элемента, для первого уровня Tags.TagName, для второго соответсвенно InfoTree.Name

Собственно вопрос, как это оптимально сделать? Если надо структуру всех таблиц можно переделать. В планах также переход на SQLite.
Единственное, на что у меня хватит знаний сейчас это строить это таблицу вручную, бегая по таблицам в цикле, но думаю это не самый лучший вариант. Жду советов!
...
Рейтинг: 0 / 0
Построение таблицы для древовидной структуры
    #36110538
olzhas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TechnoDreamer,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select a.TagID as id, - 1  as parentID, TagName 
from Tags a

union 

select a.id as id, b.TagID as parentID, a.name
from InfoTree a
inner join TagDependancy  b on a.ID = b.id
...
Рейтинг: 0 / 0
Построение таблицы для древовидной структуры
    #36110550
olzhas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
olzhas,

Предыдущий вариант это 2 уровневое дерево. Если хотите больше уровней с названием тегов на первом уровне тогда вот такой запрос. Правда я не знаю поддерживает ли Абсолют выражение case

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select a.TagID as id, - 1  as parentID, TagName 
from Tags a

union 

select 
    a.id as id, 
    case when a.ParentID = - 1   then b.TagID else a.parentID end as parentID, 
    a.name
from InfoTree a
inner join TagDependancy  b on a.ID = b.id

Все писалось руками так что могут быть ошибки, но думаю смысл вы поймете.
...
Рейтинг: 0 / 0
Построение таблицы для древовидной структуры
    #36112307
TechnoDreamer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дело в том, что InfoTree.ID и Tags.TagID уникальные идентификаторы только в пределах своей таблицы. В вашем примере, в результирующей таблице могут быть повторяющиеся поля, а этого надо избежать...
...
Рейтинг: 0 / 0
Построение таблицы для древовидной структуры
    #36112586
olzhas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TechnoDreamer,

Что мешает поставить уникальность на поля TagID,ID в таблице TagDependancy ? Так как только из-за нее может быть дублирование.
...
Рейтинг: 0 / 0
Построение таблицы для древовидной структуры
    #36113015
a.TagID (PK из Tags) вполне может совпасть с a.ID (PK из InfoTree) - тогда в результате запроса действительно будут повторяющиеся значения. А если так как-нибудь:
Код: plaintext
1.
2.
3.
4.
5.
6.
select -a.TagID as id,  0  as parentID, TagName 
from Tags a
union 
select a.id as id, -b.TagID as parentID, a.name
from InfoTree a
inner join TagDependancy  b on a.ID = b.id
...
Рейтинг: 0 / 0
Построение таблицы для древовидной структуры
    #36122385
TechnoDreamer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторЧто мешает поставить уникальность на поля TagID,ID в таблице TagDependancy ? Так как только из-за нее может быть дублирование.

Не понял вас :-)

авторa.TagID (PK из Tags) вполне может совпасть с a.ID (PK из InfoTree) - тогда в результате запроса действительно будут повторяющиеся значения. А если так как-нибудь:
Интересное решение, но к сожалению только половинчатое. Мы решаем проблему дубликатов a.TagID с a.ID. Но всё равно остаются дубликаты в случае когда одному ID соответствует несколько TagID, т.е. когда у элемента есть несколько тэгов.

Думаю на основе существующих ключей эту проблему не решить, хоть могу и ошибаться. Но этого и не требуется. Надо видимо строить отдельную иерархию, вопрос только можно ли сделать это запросом на SQL (что бы СУБД этим занималась), или же мне придется строить ее самостоятельно в Дельфи...
...
Рейтинг: 0 / 0
Построение таблицы для древовидной структуры
    #36122398
TechnoDreamer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Для большей наглядности вложил пример.

Дерево элементов многоуровневое. Элементам назначены некоторые теги (может быть несколько, а может вообще не быть). Внизу пример необходимого в результате дерева тэгов.
В вашем решении из-за того что "Тэг 1" есть у двух элементов - получается неуникальный ключ.
...
Рейтинг: 0 / 0
Построение таблицы для древовидной структуры
    #36123539
Если цель сводится к тому, чтобы обеспечить уникальность идентификаторов в этой выборке, которая будет использоваться только для отображения в визуальном компоненте, то можно было бы добавить суррогатный первичный ключ к TagDependency
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE TABLE TagDependancy (
PK_ID LARGEINT 
TagID LARGEINT,
ID LARGEINT,
CONSTRAINT "TagDependancy_pkey" PRIMARY KEY(PK_ID)
);

CREATE UNIQUE INDEX "tagdependency_idx" ON TagDependancy 
  USING btree (TagID, ID);
а сам селект записать так:
Код: plaintext
1.
2.
3.
4.
select -a.TagID as ID, NULL as parentID, a.TagName as somename
from Tags a
union 
select /*a.id*/ b.PK_ID as ID, -b.TagID as parentID, a.Name as somename
from InfoTree a inner join TagDependancy  b on a.ID = b.ID
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Построение таблицы для древовидной структуры
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]