Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Хранение иерархий-деревьев с историей изменений / 24 сообщений из 24, страница 1 из 1
06.11.2006, 21:56
    #34107783
k_traut
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Существуют ли какие-либо красивые способы хранения истории изменений для деревьев Celko?

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

Основная проблема в том, что дерево переобсчитывается при серьёзных изменениях (перемещения ветвей, допустим), причём левый и правый счётчики меняются для всех элементов и, соответственно, запросы на поиск версий и восстановления состояний получаются уж очень монструозными - плюс сопровождаются новым пересчётом.

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

Конечно, правильно деревья хранить в XML, но это часть большой базы, которую в остальном вполне себе реляционна, и дробление её по технологиям не выглядит слишком разумным.

Если это уже обсуждалось, буду благодарен за ссылку, но я ничего подобного не нашёл ни в русском, ни в англоязычном поиске.
...
Рейтинг: 0 / 0
06.11.2006, 23:20
    #34107854
guest_20040621
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
> Существуют ли какие-либо красивые способы хранения истории изменений
> для деревьев Celko?

"Деревья Celko" - они не для практического применения, Вас кто-то обманул.

> в стиле "завести таблицу такую-же-но-со-столбцом-времени-изменения"

Это самое кривое из возможных решений. Странно, что Вы не нашли других. Поищите, в этом форуме проблема обсуждалась раз пятьсот, наверное.
...
Рейтинг: 0 / 0
06.11.2006, 23:24
    #34107862
k_traut
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
e"Деревья Celko" - они не для практического применения, Вас кто-то обманул.

"А мужики-то не знают"

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

Поискал, ничего не нашёл (и не только на этом сайте). Может, конечно, плохо искал, буду благодарен за ссылку.

Пока что самое разумное из предложенного (спросил тоже не только здесь) - хранить отдельно таблицу с id/parent_id и историю для неё, а дерево каждый раз при изменении пересчитывать заново.
...
Рейтинг: 0 / 0
06.11.2006, 23:58
    #34107891
guest_20040621
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
> "А мужики-то не знают"

И чьи это проблемы?

> буду благодарен за ссылку

Легко. http://sql.ru/forum/actualsearch.aspx
Искать (кто бы мог подумать!) "история изменений".

> самое разумное из предложенного

Это "разумное" из серии "деревьев Celko", "схемы Тенцера" и пр. чуши. Т. е. прочесть, посмеяться и забыть.
...
Рейтинг: 0 / 0
07.11.2006, 00:09
    #34107907
k_traut
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Уточнение: широко обсуждаются проблемы хранения изменений для плоских данных. Однако при необходимости хранения иерархических изменений подобные методы не годятся по причинам, высказанным в самом первом посте.

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

Если вы считаете, что этот подход заведомо неэффективен, так и скажите, а ещё лучше объясните почему.

А посылать "в Яндекс", где в сотый раз выбирают между "ввести поле Deleted" и "ввести таблицу-клон" я и сам умею.
...
Рейтинг: 0 / 0
07.11.2006, 01:03
    #34107947
guest_20040621
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
> плоских данных

Дружище, выбрасывайте на свалку Вашу доморощенную терминологию. Не бывает ни плоских, ни узких, ни длинных, ни каких-нибудь еще данных.

> методы алгоритмической оптимизации

То, что Вы назвали "методами алгоритмической оптимизации" не имеет ни малейшего отношения к хранению истории изменений.

> подход заведомо неэффективен

Я не вижу подхода. Я вижу корявую поделку. Чтобы объяснить, почему она корявая, нужно начинать это делать сильно издалека и по крайней мере в уверенности, что Дейта Вы прочли полностью. У меня такой уверенности нет.
...
Рейтинг: 0 / 0
07.11.2006, 07:27
    #34108065
k_traut
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Спасибо, до свидания.
...
Рейтинг: 0 / 0
07.11.2006, 11:36
    #34108534
guest_20040621
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
> до свидания

Пока-пока.

Хотя мне было бы приятнее прочесть о том, что Вы с утра уже заказали "Введение в системы баз данных". Дружище, Вы напрасно расстроились; Вы даже не представляете, сколько времени я Вам сэкономил.
...
Рейтинг: 0 / 0
07.11.2006, 11:40
    #34108553
k_traut
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Это я вам "до свидания" сказал. А сам пока ещё тут постою, послушаю.
...
Рейтинг: 0 / 0
07.11.2006, 13:47
    #34109042
sp
sp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Я думаю что либо статусом рулить либо всета-ки доп колонками "С" "По"
они не затрагивают структуру, но позволяют их игнорировать или неигнорироватьв зависимости от условий
...
Рейтинг: 0 / 0
29.12.2006, 16:52
    #34233129
zeroandr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Деревья Celko очень даже хорошо применяются и позволяют делать простые выборки веток, подветок и т.д. Посмотреть реальный пример можно на сайте MySql. Где-то в топиках была прямая ссылка, правда разобраться в методе не так просто, но для умного человека там ничего сложного нет.
А на guest_20040621 не обращайте внимания он во многих ветках гонит полную пургу без дела)
...
Рейтинг: 0 / 0
01.01.2007, 15:39
    #34234483
zeroandr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
zeroandrДеревья Celko очень даже хорошо применяются и позволяют делать простые выборки веток, подветок и т.д. Посмотреть реальный пример можно на сайте MySql. Где-то в топиках была прямая ссылка, правда разобраться в методе не так просто, но для умного человека там ничего сложного нет.
А на guest_20040621 не обращайте внимания он во многих ветках гонит полную пургу без дела)
PS: вот нашел ссылку http://dev.mysql.com/tech-resources/articles/hierarchical-data.html, там есть процедуры добавления, вставки и удаления веток их можно доработать в плане сохранения истории.
...
Рейтинг: 0 / 0
01.01.2007, 15:54
    #34234487
zeroandr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Для хранения истории, например, можно к стандартной таблице по Селко добавить две даты : дату создания ветки и дату удаления и соответсвенно изменить запрос на построение дерева в соответствии с текущей датой, при создании веток вставлять дату создания а при удалении обновлять дату удаления, тогда на любой момент времени можно будет построить дерево таким, каким оно было тогда.
...
Рейтинг: 0 / 0
01.01.2007, 17:37
    #34234516
k_traut
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Спасибо.
...
Рейтинг: 0 / 0
01.01.2007, 17:47
    #34234519
ОКТОГЕН
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
zeroandr zeroandrДеревья Celko очень даже хорошо применяются и позволяют делать простые выборки веток, подветок и т.д. Посмотреть реальный пример можно на сайте MySql. Где-то в топиках была прямая ссылка, правда разобраться в методе не так просто, но для умного человека там ничего сложного нет.
А на guest_20040621 не обращайте внимания он во многих ветках гонит полную пургу без дела)
PS: вот нашел ссылку http://dev.mysql.com/tech-resources/articles/hierarchical-data.html, там есть процедуры добавления, вставки и удаления веток их можно доработать в плане сохранения истории.
Позволю себе вмешаться. Я бы не стал вообще связываться с Celko.
У этого метода есть очень серьезные недостатки. Если Вам будет нужно что-то поменять в дереве, то Вам придется передергивать ВСЕ данные в соответствующих таблицах. Кроме того, хранить можно только одно дерево , если их много, то придется клонировать эту структуру для других деревьев. Попробуйте взять класическую схему отец-сын и модифицировать ее для ваших нужд.
Мне кажется, это будет проще.
...
Рейтинг: 0 / 0
01.01.2007, 17:53
    #34234521
k_traut
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Пересчитывать каждый раз приходится только в Nested Sets, в модели Nested Intervals пересчёт требуется значительно реже, когда кончается выделенный диапазон. Кроме того, можно пересчитывать только поддерево, а не дерево целиком.
...
Рейтинг: 0 / 0
04.01.2007, 16:44
    #34237153
soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
k_traut e"Деревья Celko" - они не для практического применения, Вас кто-то обманул.

"А мужики-то не знают"


Они работают только в случае редкоизменяемых данных, там где количество операций чтения выше чем количество операция записи на 3-4 порядка или же количество элементов не выше 10^5.
...
Рейтинг: 0 / 0
08.01.2007, 18:14
    #34241395
Кот Матроскин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Деревья Селко используются тогда, когда требуется дешевый запрос "все потомки данного узла" (без использования connect by и прочей экзотики). У альтернативных способов это обеспечить возникают примерно такие же проблемы с модификациями данных, как и у Селко.
Сравнивать деревья Селко с моделью "отец-сын" некорректно - у них разная функциональность.
...
Рейтинг: 0 / 0
25.01.2007, 08:30
    #34280665
Paul Chabinsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Я делал реализацию иерархий на основе вложенных множеств...
В приципе ничего сложного там нет, на мой взгляд...
Да, проблемма, с обновлением существует, но можно сделать не дерево, а лес деревьев, причем добавив всего одно поле...
Я остановился на следующем примере, если интерестно (пытался обсуждать на форуме реализацию, но толку никакого):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
--Табличка, думаю поля и так будут понятны, индексы под свои задачи сделаете
CREATE TABLE [Category] (
	[cat_id] [int] IDENTITY ( 1 ,  1 ) NOT NULL ,
	[cat_parent] [int] NULL ,
	[cat_left] [int] NULL ,
	[cat_right] [int] NULL ,
	[cat_level] [int] NULL ,
	[cat_name] [varchar] ( 100 ) COLLATE Cyrillic_General_CI_AS NOT NULL ,
	CONSTRAINT [PK_Category] PRIMARY KEY  NONCLUSTERED 
	(
		[cat_id]
	)  ON [PRIMARY] ,
	CONSTRAINT [IX_Category_Category] UNIQUE  CLUSTERED 
	(
		[cat_left],
		[cat_right],
		[cat_level]
	)  ON [PRIMARY] ,
	CONSTRAINT [FK_Category_Category] FOREIGN KEY 
	(
		[cat_parent]
	) REFERENCES [Category] (
		[cat_id]
	)
) ON [PRIMARY]
GO
--Просто вспомогательная процедурка, считает "координаты",  упрощает перемещение и вставку.
CREATE  PROC admin_p_CategoryPoint
(
	@cat_id int, @axis_x bit, @axis_y bit,
	@pnt_parent int output,
	@pnt_point int output,
	@pnt_level int output
)
AS
	SET NOCOUNT ON
	DECLARE @cat_parent int, @cat_left int, @cat_right int, @cat_level int
	SELECT @cat_parent = cat_parent, @cat_left = cat_left, @cat_right = cat_right, @cat_level = cat_level
		FROM dbo.Category WHERE cat_id = @cat_id	
	IF @axis_y =  1 
		BEGIN
			SET @pnt_parent = @cat_id
			IF @axis_x =  1  SET @pnt_point = @cat_right -  1  ELSE SET @pnt_point = @cat_left
			SET @pnt_level = @cat_level +  1 
		END
	ELSE
		BEGIN
			SET @pnt_parent = @cat_parent
			IF @axis_x =  1  SET @pnt_point = @cat_right ELSE SET @pnt_point = @cat_left - 1 
			SET @pnt_level = @cat_level
		END

GO
--Процедурка, добавляет ноду.
CREATE PROC admin_p_CategoryIns 
(
	@cat_id int output,
	@cat_parent int,
	@axis_x bit,
	@axis_y bit,
	@cat_name varchar ( 100 )
)
AS
	SET NOCOUNT ON
	DECLARE @pnt_parent int, @pnt_point int, @pnt_level int
	EXEC dbo.admin_p_CategoryPoint @cat_parent, @axis_x, @axis_y,
		@pnt_parent OUTPUT , @pnt_point OUTPUT , @pnt_level OUTPUT
	UPDATE dbo.Category SET 
		cat_left	= CASE WHEN cat_left > @pnt_point THEN cat_left +  2  ELSE cat_left END,
		cat_right	= cat_right +  2 
	WHERE cat_right > @pnt_point
	INSERT INTO dbo.Category (cat_parent, cat_left, cat_right, cat_level, cat_name)
		VALUES (@pnt_parent, @pnt_point +  1 , @pnt_point +  2 , @pnt_level, @cat_name)
	SELECT @cat_id = SCOPE_IDENTITY()

GO
--Процедурка, перемещает ноду
CREATE PROC admin_p_CategoryUpd
(
	@cat_id int,
	@cat_parent int,
	@axis_x bit,
	@axis_y bit,
	@cat_name varchar ( 100 )
)
AS
	SET NOCOUNT ON

	DECLARE @cat_left int, @cat_right int, @cat_level int
	SELECT @cat_left = cat_left, @cat_right = cat_right, @cat_level = cat_level
		FROM dbo.Category WHERE cat_id = @cat_id

	DECLARE @pnt_parent int, @pnt_point int, @pnt_level int
	EXEC dbo.admin_p_CategoryPoint @cat_parent, @axis_x, @axis_y,
		@pnt_parent OUTPUT , @pnt_point OUTPUT , @pnt_level OUTPUT

	IF @pnt_point BETWEEN @cat_left AND @cat_right
		RAISERROR ('#00012',  16 ,  1 )

	DECLARE @d1 int, @d2 int, @d3 int
	SET @d1 = @cat_right - @cat_left +  1 
	SET @d2 = @pnt_level - @cat_level

	IF @pnt_point > @cat_right
		BEGIN
			SET @d3 = @pnt_point - @cat_right
			UPDATE dbo.Category SET
				cat_left = CASE WHEN cat_right <= @cat_right THEN cat_left + @d3 ELSE CASE WHEN cat_left > @cat_right THEN cat_left - @d1 ELSE cat_left END END,
				cat_right = CASE WHEN cat_right <= @cat_right THEN cat_right + @d3 ELSE CASE WHEN cat_right <= @pnt_point THEN cat_right - @d1 ELSE cat_right END END,
				cat_level = CASE WHEN cat_right <= @cat_right THEN cat_level + @d2 ELSE cat_level END
			WHERE cat_left <= @pnt_point AND cat_right > @cat_left
		END
	ELSE
		BEGIN
			SET @d3 = @pnt_point - @cat_left +  1 
			UPDATE dbo.Category SET
				cat_right = CASE WHEN cat_left >= @cat_left THEN cat_right + @d3 ELSE CASE WHEN cat_right < @cat_left THEN cat_right + @d1 ELSE cat_right END END,
				cat_left = CASE WHEN cat_left >= @cat_left THEN cat_left + @d3 ELSE CASE WHEN cat_left > @pnt_point THEN cat_left + @d1 ELSE cat_left END END,
				cat_level = CASE WHEN cat_left >= @cat_left THEN cat_level + @d2 ELSE cat_level END
			WHERE @cat_right > cat_left AND @pnt_point < cat_right
		END

	UPDATE dbo.Category SET
		cat_parent = @pnt_parent,
		cat_level = @pnt_level,
		cat_name = @cat_name
	WHERE cat_id = @cat_id
GO
...
Рейтинг: 0 / 0
25.01.2007, 08:56
    #34280704
k_traut
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Большое спасибо.
...
Рейтинг: 0 / 0
25.01.2007, 09:17
    #34280737
Paul Chabinsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Немного поясню...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
-- ну собственно нода на которой будет происходить
-- преобразование (включая ее дочерние элементы), назовем ее "A"
@cat_id int,

-- вот тут маленькая поправка, это не просто родитель,
-- это нода относительно которой будем ориентироваться при вставка/перемещении "A", назовем ее "B"
@cat_parent int,

-- дополнительные флаги
@axis_x bit,  @axis_y bit,  Результат
  false,        false         "A" встанет на одном уровне с "B", до "B"
  false,        true          "A" встанет на одном уровне с "B", после "B"
  true,         false         "A" станет первым дочерним элементом "B"
  true,         true          "A" станет последним дочерним элементом "B"
...
Рейтинг: 0 / 0
25.01.2007, 17:49
    #34283011
Роман Дынник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
На практике получается что ID-ParentID нужно все равно хранить даже для деревьев Celko (удобно при использовании всяких компонент и прочего), ну а раз ID-ParentID хранится, то почему бы ее не задействовать в истории. т.е. в истории вместо индексов правых и левых узлов храним ParentID. При необходимости восстановления из истории, просто конвертируем связи ID-ParentID в разметку дерева левыми и правыми индексами.
В принципе и left-rigth, если есть необходимость, можно тоже в истории хранить. Ведь добавление/изменение узлов наверняка в хп происходит, там же и историю создавать можно для задействованного в операции ins/upd/delete поддерева.
...
Рейтинг: 0 / 0
26.01.2007, 10:05
    #34284150
Estets
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
Роман ДынникНа практике получается что ID-ParentID нужно все равно хранить даже для деревьев Celko (удобно при использовании всяких компонент и прочего),
+1 Полностью поддерживаю, т.к. часто необходимо узнать потомков первого уровня для узла, а не всех (что намного проще для Celko деревьев)
...
Рейтинг: 0 / 0
26.01.2007, 13:39
    #34285213
guest_20040621
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранение иерархий-деревьев с историей изменений
> На практике получается что ID-ParentID нужно все равно хранить даже для деревьев Celko

Ага. Только это уже не деревья Celco.
...
Рейтинг: 0 / 0
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Хранение иерархий-деревьев с историей изменений / 24 сообщений из 24, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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