这适用于小型调度应用。我需要一种算法来有效地比较两个“时间表”,找到差异,并仅更新已更改的数据行,以及将此表作为外键的另一个表中的条目。这是一个很大的问题,所以我马上就说我正在寻找一般建议或特定解决方案。
编辑:正如所建议的那样,我已经大大缩短了这个问题。
在一个表中,我将资源与使用它们的时间段相关联。
我还有第二个表(表B),它使用表A中的ID作为外键。
表A中对应于表B的条目将具有包含来自表B的时间跨度的时间跨度。并非表A中的所有条目都具有表B中的条目。 / p>
我正在为用户提供一个界面,用于编辑表A中的资源调度。它们基本上为表A提供了一组新的数据,我需要将其视为来自版本的 diff DB。
如果他们从表A中完全删除表A中的对象,我也希望从表B中删除该条目。
所以,考虑到以下3组:
我需要一种算法:
只需将对象排序到我可以应用适当数据库操作的安排中,这对解决方案来说已经足够了。
同样,请按照具体或通常进行回答,我正在寻求建议,但如果某人有完整的算法可以让我的一天。 :)
编辑:为了回应lassvek,我提供了一些额外的细节:
表B的项目始终完全包含在表A项目中,而不仅仅是重叠。
重要的是,表B的项目是量化的,因此它们应该完全落入或完全落在外面。如果没有发生这种情况,那么我有一个数据完整性错误,我必须单独处理。
例如(使用速记):
Table A ID Resource Start End 01 Resource A 10/6 7:00AM 10/6 11:00AM 02 Resource A 10/6 1:00PM 10/6 3:00PM Table B ID Table_A_ID Start End 01 02 10/6 1:00PM 10/6 2:00PM
所以我想要以下行为:
答案 0 :(得分:7)
我已经广泛地使用了句号,但我担心我不完全理解表A和B如何协同工作,也许这是我不理解的 subsume 这个词。
你能举出一些你想做的具体例子吗?
你的意思是表A中记录的时间跨度包含表B中的完全时间跨度,就像这样?
|---------------- A -------------------|
|--- B ----| |--- B ---|
或与?
重叠 |---------------- A -------------------|
|--- B ----| |--- B ---|
或相反的方式,B中的时间跨度包含/与A?
重叠让我们说它是第一个,其中B中的时间跨度与表A中的链接时间跨度相同。
这是否意味着:
* A removed A-timespan removes all the linked timespans from B
* An added A-timespan, what about this?
* A shortened A-timespan removes all the linked timespans from B that now falls outside A
* A lenghtened A-timespan, will this include all matching B-timespans now inside?
以下是一个例子:
|-------------- A1 --------------| |-------- A2 --------------|
|---- B1 ----| |----- B2 ---| |---- B3 ----| |-- B4 --|
然后你加长A1并缩短并移动A2,以便:
|-------------- A1 ---------------------------------| |--- A2 --|
|---- B1 ----| |----- B2 ---| |---- B3 ----| |-- B4 --|
这意味着你想修改这样的数据:
1. Lengthen (update) A1
2. Shorten and move (update) A2
3. Re-link (update) B3 from A2 to A1 instead
这个修改怎么样,A1被加长了,但不足以完全包含B3,A2以同样的方式移动/缩短:
|-------------- A1 -----------------------------| |--- A2 --|
|---- B1 ----| |----- B2 ---| |---- B3 ----| |-- B4 --|
由于B3现在不完全在A1或A2范围内,请将其删除?
我需要一些具体的例子来说明你想做什么。
修改更多问题
好的,怎么样:
|------------------ A -----------------------|
|------- B1 -------| |------- B2 ------|
|---| <-- I want to remove this from A
这个怎么样?
或者:
|------------------ A1 ----| |---- A2 -----|
|------- B1 -------| |B3| |--- B2 ---|
或:
|------------------ A1 ----| |---- A2 -----|
|------- B1 -------|
总结我到目前为止如何看待问题:
我将在C#中实施一个可能在我下班回家时工作的实现,今晚我会再回来。
编辑以下是对算法的抨击。
您应该创建大量的单元测试,并确保涵盖所有修改组合。
答案 1 :(得分:2)
我建议你将问题分成两个单独的问题: 第一个应该是这样的:“当将一个计划原子表示为具有开始时间和结束时间的资源时,我如何推理资源调度?”在这里,ADept建议使用区间代数似乎是合适的。请参阅The Wikipedia entry 'Interval Graph'和The SUNY algorithm repository entry on scheduling。 第二个问题是数据库问题:“给定一个算法来调度间隔并指示两个间隔是否重叠或一个是否包含在另一个间隔中,如何使用此信息来管理给定模式中的数据库?”我相信一旦调度算法到位,数据库问题将更容易解决。 HTH, 尤瓦
答案 2 :(得分:1)
你发帖几乎是在“太长;没读”的类别 - 缩短它可能会给你更多的反馈。
无论如何,关于主题:您可以尝试查看名为"Interval Algebra"
的内容答案 3 :(得分:1)
据我了解,您的用户只能直接影响表A.假设您使用C#编程,您可以使用简单的ADO.Net DataSet来管理对表A的修改.TableAdapter知道单独保留未触动的行并且适当地处理新的,修改的和删除的行。
此外,您应该定义级联删除,以便自动删除表B中的相应对象。
唯一不以这种方式处理的情况是,如果表A中的时间跨度缩短了s.t.它不再包含表B中的相应记录。您只需在更新存储过程中检查该情况,或者在表A上定义更新触发器。
答案 4 :(得分:1)
在我看来,任何算法都需要通过NewA,匹配ResourceID,StartTime和EndTime,并跟踪OldA中的哪些元素被击中。然后你有两组不匹配的数据,UnmatchedNewA和UnmatchedOldA。
我能想到的最简单的方法是基本上重新开始: 将所有UnmatchedNewA写入DB,将UnmatchedOldA中的B元素转移到新A键(刚生成),尽可能删除。然后清掉所有UnmatchedOldA。
如果有很多变化,这肯定不是一种有效的方法。但是,如果数据的大小不是很大,我更喜欢简单到聪明的优化。
在没有更多背景的情况下,不可能知道这个最终建议是否有意义,但是如果你没有这样想的话,这是不可能的:
您是否可以使用事件监听器或类似的东西来更新数据模型而不是需要进行更改,而不是来回传递整个A集合?这样,被更改的对象将能够确定动态需要哪些DB操作。