Какие алгоритмы известны для выполнения задачи обновления базы данных путем вставки, обновления и удаления строк при наличии ограничений базы данных?
Более конкретно, скажем, что перед изображениями строк, которые должны быть удалены, после изображений строк, которые должны быть вставлены, и оба изображения строк, которые должны быть обновлены, находятся в памяти. Строки могут быть для нескольких таблиц. Точная последовательность обновлений либо неизвестна, либо не сохранена - известны только изображения до и после, которые должна отражать база данных.
База данных содержит ограничения первичного ключа, внешнего ключа и уникального индекса. Проблема в том, чтобы найти последовательность команд для обновления базы данных. Для простоты я хочу указать, что первичный ключ строки никогда не будет изменен.
Система базы данных не поддерживает отложенную проверку ограничений. (Для таких баз данных решение тривиально). Я также должен установить правило, согласно которому столбцы первичного ключа не могут обновляться после вставки, и не разрешается удалять строку и повторно вставлять ее с тем же первичным ключом, даже если некоторые алгоритмы могут в противном случае счесть это удобным. (Это необходимо для распространенных сценариев, когда все первичные ключи автоматически генерируются системой базы данных.)
Какие бывают алгоритмы:
- Предполагается, что ограничения внешнего ключа должны применяться постоянно, но уникальные индексы не используются.
- Предполагается, что ограничения внешнего ключа и ограничения уникального индекса должны выполняться всегда.
Я прошу и то, и другое, потому что считаю, что №1 может быть значительно проще.
РЕДАКТИРОВАТЬ: цель здесь - решить проблему отсутствия отложенной проверки ограничений общим (или почти универсальным) способом. Я полагаю, что это должны делать высококачественные пакеты ORM. Мне нужно объяснение алгоритмов, предоставленное вами здесь или извне в академической статье и т. Д. Я не буду рассматривать указатель на программный пакет или исходный код ответом на этот вопрос.
НАИВНЫЙ АЛГОРИТМ:
Просмотрите таблицы и для каждой добавленной, измененной или удаленной строки сгенерируйте по одному оператору INSERT, UPDATE или DELETE соответственно для каждой. Прокрутите сгенерированные операторы и примените к базе данных. Если утверждение не применимо, переходите к другим утверждениям. Повторите неудачные попытки. Продолжайте повторять, пока не будет больше сбоев или пока на проходе не будет успешно выполнено ни одного оператора. Если операторы остаются, попробуйте временную настройку данных в проблемных столбцах, чтобы попытаться добиться успеха.
Это уродливый алгоритм грубой силы, и выяснение части "временной настройки" - отдельная задача. Итак, мне нужен улучшенный и полный алгоритм.
РЕДАКТИРОВАТЬ2:
RBarryYoung публикует ответ, который приближается (но без сигары) к полному решению сценария №1 при одновременном решении наиболее распространенных проблем сценария №2. Ниже приводится пример шаблона обновления сценария №1, который я видел очень часто в приложениях, но еще не нашел решения. DELETE / UPDATE-INSERT в большинстве случаев является правильным в сценарии № 1, но уловка состоит в том, чтобы выяснить, когда от него следует отклониться. Я также подозреваю, что отклонение от него увеличивает возникновение УНИКАЛЬНЫХ проблем для сценария №2, что, возможно, также увеличивает мой интерес к решению сценария №2.
Обратите внимание, что нет ни циклов, ни каких-либо измененных первичных ключей. Однако внешний ключ родителя изменяется.
CREATE TABLE A
(
AId INT NOT NULL PRIMARY KEY
)
CREATE TABLE B
(
BId INT NOT NULL PRIMARY KEY,
AId INT NOT NULL FOREIGN KEY REFERENCES A (AId)
)
CREATE TABLE C
(
CId INT NOT NULL PRIMARY KEY,
AId INT NOT NULL FOREIGN KEY REFERENCES A (AId),
BId INT NOT NULL FOREIGN KEY REFERENCES B (BId)
)
Перед изображениями:
A (1)
B (1,1)
C (1,1,1)
После изображений:
A (1)
B (2,1) [To be deleted: (1,1)]
C (1,1,2)
Порядок сортировки: A, B, C
Первая команда - это DELETE B (1,1), которая не выполняется из-за C (1,1,1).
Обратите внимание, что если третий столбец в C допускает NULL (чего он не делает в данном случае), чистое решение может включать в себя удаление NULL на раннем проходе, так как это позволит данному алгоритму работать нормально и иметь свои обычные преимущества для работы с большинство проблем сценария №2. Отличное решение этой проблемы должно учитывать и подобные вещи. Полная общность этого вопроса, несомненно, интересная проблема.