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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Пока-пока.

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

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


Они работают только в случае редкоизменяемых данных, там где количество операций чтения выше чем количество операция записи на 3-4 порядка или же количество элементов не выше 10^5.
...
Рейтинг: 0 / 0
Хранение иерархий-деревьев с историей изменений
    #34241395
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Деревья Селко используются тогда, когда требуется дешевый запрос "все потомки данного узла" (без использования connect by и прочей экзотики). У альтернативных способов это обеспечить возникают примерно такие же проблемы с модификациями данных, как и у Селко.
Сравнивать деревья Селко с моделью "отец-сын" некорректно - у них разная функциональность.
...
Рейтинг: 0 / 0
Хранение иерархий-деревьев с историей изменений
    #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
Хранение иерархий-деревьев с историей изменений
    #34280704
k_traut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Большое спасибо.
...
Рейтинг: 0 / 0
Хранение иерархий-деревьев с историей изменений
    #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
Хранение иерархий-деревьев с историей изменений
    #34283011
Фотография Роман Дынник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На практике получается что ID-ParentID нужно все равно хранить даже для деревьев Celko (удобно при использовании всяких компонент и прочего), ну а раз ID-ParentID хранится, то почему бы ее не задействовать в истории. т.е. в истории вместо индексов правых и левых узлов храним ParentID. При необходимости восстановления из истории, просто конвертируем связи ID-ParentID в разметку дерева левыми и правыми индексами.
В принципе и left-rigth, если есть необходимость, можно тоже в истории хранить. Ведь добавление/изменение узлов наверняка в хп происходит, там же и историю создавать можно для задействованного в операции ins/upd/delete поддерева.
...
Рейтинг: 0 / 0
Хранение иерархий-деревьев с историей изменений
    #34284150
Estets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Роман ДынникНа практике получается что ID-ParentID нужно все равно хранить даже для деревьев Celko (удобно при использовании всяких компонент и прочего),
+1 Полностью поддерживаю, т.к. часто необходимо узнать потомков первого уровня для узла, а не всех (что намного проще для Celko деревьев)
...
Рейтинг: 0 / 0
Хранение иерархий-деревьев с историей изменений
    #34285213
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> На практике получается что ID-ParentID нужно все равно хранить даже для деревьев Celko

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


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