Это для небольшого приложения для планирования. Мне нужен алгоритм для эффективного сравнения двух «расписаний», поиска различий и обновления только тех строк данных, которые были изменены, а также записей в другой таблице, имеющей эту таблицу в качестве внешнего ключа. Это большой вопрос, поэтому сразу скажу, ищу либо общий совет, либо конкретные решения.
Обновлено: Как было предложено, я значительно сократил вопрос.
В одной таблице я связываю ресурсы с промежутком времени, когда они используются.
У меня также есть вторая таблица (таблица B), которая использует идентификатор из таблицы A в качестве внешнего ключа.
Запись из таблицы A, соответствующая таблице B, будет иметь интервал времени, который включает - интервал времени из таблицы B. Не все записи в таблице A будут иметь запись в таблице B.
Я предоставляю пользователям интерфейс для редактирования расписания ресурсов в таблице A. Они в основном предоставляют новый набор данных для таблицы A, который мне нужно рассматривать как разница из версии в базе данных.
Если они полностью удаляют объект из таблицы A, на который указывает таблица B, я хочу также удалить запись из таблицы 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
Поэтому мне нужно следующее поведение:

Ваш пост почти попал в категорию "слишком длинный; не читал" - сокращение, вероятно, даст вам больше отзывов.
Во всяком случае, по теме: вы можете попробовать заглянуть в штуку под названием «Алгебра интервалов»
Насколько я понимаю, ваши пользователи могут напрямую влиять только на таблицу A. Предполагая, что вы программируете на C#, вы можете использовать простой набор данных ADO.Net для управления изменениями в таблице A. TableAdapter знает, что нужно оставлять нетронутые строки в покое и обрабатывать новые, измененные и удаленные строки соответствующим образом.
Кроме того, вы должны определить каскадное удаление, чтобы автоматически удалять соответствующие объекты в таблице B.
Единственный случай, который не обрабатывается таким образом, - это сокращение временного интервала в таблице A s.t. он больше не включает соответствующую запись в Таблицу B. Вы можете просто проверить этот случай в хранимой процедуре обновления или, в качестве альтернативы, определить триггер обновления в таблице A.
Мне кажется, что любой алгоритм для этого будет включать прохождение NewA, сопоставление ResourceID, StartTime и EndTime и отслеживание того, какие элементы из OldA попадают. Затем у вас есть два набора несовпадающих данных: UnmatchedNewA и UnmatchedOldA.
Самый простой способ, который я могу придумать, - это в основном начать с этих: Запишите все UnmatchedNewA в базу данных, перенесите элементы B из UnmatchedOldA в новые ключи A (только что сгенерированные), где это возможно, удаляя, если нет. Затем сотрите все UnmatchedOldA.
Если изменений много, это, безусловно, неэффективный способ продолжения. Однако в тех случаях, когда размер данных не слишком велик, я предпочитаю простоту умной оптимизации.
Невозможно узнать, имеет ли это последнее предложение какой-либо смысл без дополнительной информации, но на случай, если вы не подумали об этом так:
Вместо того, чтобы передавать всю коллекцию A туда и обратно, могли бы вы использовать прослушиватели событий или что-то подобное для обновления модели данных только там, где необходимы изменения? Таким образом, изменяемые объекты смогут определять, какие операции с БД требуются на лету.
Я предлагаю вам разделить свои вопросы на два отдельных: Первый должен быть примерно таким: «Как я могу рассуждать о планировании ресурсов, представляя атом расписания как ресурс с временем начала и временем окончания?» Здесь предложение ADept об использовании алгебры интервалов кажется уместным. См. Запись в Википедии "Интервальный график" и Запись в репозитории алгоритма SUNY по расписанию. Второй вопрос - это вопрос базы данных: «Учитывая алгоритм, который планирует интервалы и указывает, перекрываются ли два интервала или один содержится в другом, как мне использовать эту информацию для управления базой данных в данной схеме?» Я считаю, что как только алгоритм планирования будет создан, вопрос с базой данных будет решаться намного проще. HTH, Юваль
Я много работал с точками, но боюсь, что не совсем понимаю, как таблицы A и B работают вместе, возможно, это слово относить, которое я не понимаю.
Можете ли вы привести конкретные примеры того, что вы хотите сделать?
Вы имеете в виду, что промежутки времени, записанные в таблице 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#, которая может сработать, когда я вернусь домой с работы, я вернусь с другими позже сегодня вечером.
Редактировать Вот укол алгоритма.
Вам следует создать огромный набор модульных тестов и убедиться, что вы охватываете все комбинации модификаций.
Привет, лассевк, спасибо за ответ. Да, это первый сценарий (B полностью содержится в A). Постараюсь добавить к своему запросу конкретный пример.
lassevk, я сожалею, что получил всего один голос за ваш продуманный ответ. Я наверное попробую это реализовать завтра утром!
Не беспокойтесь .. У меня тоже есть :)
Спасибо, гроссфогель, это был тот подход, который я рассматривал (уничтожение старого набора / написание нового набора). Это не казалось очень эффективным, отсюда и вопрос, но есть что сказать о подходе, который легко объяснить. Я могу поступить так.