Проектирую БД складского учёта на Firebird. см. часть диаграммы:
http://i63.fastpic.ru/big/2015/0125/...4a867e1870.png
Цель: в интерфейсе создать treeview типа:
Код:
. Фирма №1
.филиал(магазин)№1
.склад №1(основной, для товара)
. стеллаж №1
. стеллаж №2
. ящик №1(часто используется,напр, в аптеках)
. ящик №2
.склад №2(для материалов)
.склад №3(для списанного товара,пока налоговая не разрешить уничтожить)
.филиал(магазин)№2
.склад №1
. Фирма №2
и т.д.
I путь:
создать 2 иерархии:
Если в таблице Контрагенты добавлю поле ParentID, тогда смогу вставить в таблице записи филиалов и подразделении и построить первую иерархию типа:
Код:
.Фирма №1
.филиал(магазин)№1
.подразделение №1
.подразделение №2
.филиал(магазин)№2
.подразделение №3
.подразделение №4
.Фирма №2
.филиал(магазин)№3
.подразделение №5
.подразделение №6
и т.д.
Если в таблице склады добавлю поле ParentID, тогда смогу создать записи стеллажей и ящиков и построить вторую иерархию типа:
Код:
.Склад №1
.стеллаж №1
.ящик №1
.ящик №2
.стеллаж №2
.ящик №3
.ящик №4
.Склад №2
.стеллаж №3
.ящик №5
.ящик №6
и т.д.
хотя потом возникнет проблема связывания 2 иерархии.!
II путь: создать цепь таблиц Фирма-филиал-подразделение-склад-стеллаж и(или)ящик то есть как тут:
http://i64.fastpic.ru/big/2015/0129/...999e45d4a8.png.
статью про аналогичную тему прочитал тут:
http://www.opennet.ru/base/dev/hierarchy_sql.txt.html .
Цитата:
Одним из вариантов хранения таких иерархий является поуровневое
хранение в различных таблицах. Например, таблица CATALOG_LEVEL_1
хранит все элементы первого уровня вложенности, таблица
CATALOG_LEVEL_2 - второго, и т.д. Ниже приведено описание такой
структуры для случая трехуровневой иерархии.
CREATE TABLE "CATALOG3_LEVEL1" (
"ID" INTEGER NOT NULL PRIMARY KEY,
"NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL
);
CREATE TABLE "CATALOG3_LEVEL2" (
"ID" INTEGER NOT NULL UNIQUE,
"NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL,
"PARENT_ID" INTEGER NOT NULL REFERENCES "CATALOG3_LEVEL1"("ID"),
PRIMARY KEY("ID","PARENT_ID")
);
CREATE TABLE "CATALOG3_LEVEL3" (
"ID" INTEGER NOT NULL UNIQUE,
"NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL,
"PARENT_ID" INTEGER NOT NULL REFERENCES "CATALOG3_LEVEL1"("ID"),
"PARENT_ID2" INTEGER NOT NULL REFERENCES "CATALOG3_LEVEL2"("ID"),
PRIMARY KEY ("ID", "PARENT_ID", "PARENT_ID2")
);
.....
Получение всех потомков
Довольно часто возникает задача получения всех, в том числе и не
прямых потомков данного элемента. Рассмотрим решение этой задачи для приведенных структур.
структура с потабличным хранением уровней
Потомки данного элемента содержатся в "нижележащих" таблицах и имеют как часть составной ссылки на предка в одном из полей значение ID предка. Общий список потомков можно получить объединением (UNION) запросов.
select "ID",'1' as "LEVEL" from CATALOG3_LEVEL2 where PARENT_ID = 1
union
select "ID",'2' as "LEVEL" from CATALOG3_LEVEL3 where PARENT_ID = 1
Ввод дополнительного поля LEVEL в запрос обусловлен тем, что потомки элемента в разных таблицах могут иметь одинаковые ID и при объединении запросов вместо нескольких строк в результате будет получена одна. Еще одна проблема, приводящая к необходимости ввода дополнительного поля в запрос, т.к. надо знать, из какой таблицы выбран данный ID.
|
и аналогично я создал 3 таблицы: Level1,Level2,Level3:
Код:
CREATE TABLE "LEVEL1"
(
"ID" INTEGER NOT NULL,
"LEV" INTEGER,
"NAME" VARCHAR(200),
PRIMARY KEY ("ID")
CREATE TABLE "LEVEL2"
(
"ID" INTEGER NOT NULL,
"PARENT_ID" INTEGER NOT NULL,
"LEV" INTEGER,
"NAME" VARCHAR(200) NOT NULL,
PRIMARY KEY ("ID")
);
ALTER TABLE "LEVEL2" ADD FOREIGN KEY ("PARENT_ID") REFERENCES "LEVEL1" ("ID");
CREATE TABLE "LEVEL3"
(
"ID" INTEGER NOT NULL,
"PARENT_ID" INTEGER NOT NULL,
"PARENT_ID2" INTEGER NOT NULL,
"LEV" INTEGER,
"NAME" VARCHAR(200),
PRIMARY KEY ("ID")
);
ALTER TABLE "LEVEL3" ADD FOREIGN KEY ("PARENT_ID") REFERENCES "LEVEL1" ("ID");
ALTER TABLE "LEVEL3" ADD FOREIGN KEY ("PARENT_ID2") REFERENCES "LEVEL2" ("ID");
а запрос выглядит так:
Код:
select id, 0 as parent_id, lev, name from level1
union
select id, parent_id,lev, name from level2
union
select id, parent_id, lev, name from level3
но результат не тот:
Код:
ID PARENT_ID LEVEL NAME
1 0 1 BBB Ltd
1 1 2 Branch #1 of "AAA"
1 1 3 Departament №1 of AAA
2 0 1 AAA Ltd
2 1 3 Departament №2 of AAA
2 2 2 Branch #1 of "AAA"
3 2 2 Branch #2 of "BBB"
3 2 3 Departament №1 of BBB
как выдите Parent_ID собраны из всех 3 таблиц и с помощью их невозможно построить TreeView?! Знаю как строится древовидная структура на основе одной таблицы, но здесь совсем другая ситуация- ParentID не указывает на предка. Как преодолеть?