Проверка битемпоральной целостности
Необходимость в этом обусловлена тем фактом, что у нас теперь есть многочисленные источники, обновляющие чувствительные двухвременные таблицы, мы немного настороже и хотим прикрыть свои спины.
Я использовал "Разработка ориентированных на время приложений баз данных в SQL" Ричарда Снодграсса, чтобы помочь мне в этом.
Я пытался придумать триггер, который утверждает, что битемпоральные контракты удерживаются после каждого обновления или вставки. Чтобы быть более конкретными, контракты гарантируют, что первичный ключ является последовательным с действительным временем и временем транзакции, а также с непоследовательным утверждением действительной непрерывности времени. После этого утверждения приводятся ниже:
Утверждают, что в "активном" нет совпадений
VALID_TIME
график.Утверждают, что в
TRANSACTION_TIME
график.Утверждают, что нет пробелов в
VALID_TIME
график.
Под "активным" я имею в виду записи с TRANSACTION_END
значение "навсегда" (9999-12-31)
,
Вот что у меня так далеко:
CREATE OR REPLACE TRIGGER TRIGGER_NAME
AFTER INSERT OR UPDATE
ON SOME_TABLE
DECLARE
ROWCOUNT INTEGER;
BEGIN
SELECT COUNT(*) INTO ROWCOUNT
FROM SOME_TABLE T1,SOME_TABLE T2
WHERE T1.PK_COLUMN2 = T2.PK_COLUMN2
AND T1.PK_COLUMN1 = T2.PK_COLUMN1
AND T1.TRANSACTION_START < T2.TRANSACTION_END
AND T2.TRANSACTION_START < T1.TRANSACTION_END
AND T1.ROWID != T2.ROWID;
IF (ROWCOUNT>0) THEN
RAISE_APPLICATION_ERROR(-20001, 'BITEMPORAL INTEGRITY TRIGGER CHECK : AUDIT_TIME OVERLAP');
END IF;
SELECT COUNT(*) INTO ROWCOUNT
FROM SOME_TABLE T1,SOME_TABLE T2
WHERE T1.PK_COLUMN2 = T2.PK_COLUMN2
AND T1.PK_COLUMN1 = T2.PK_COLUMN1
AND T1.VALID_START < T2.VALID_END
AND T2.VALID_START < T1.VALID_END
AND T1.TRANSACTION_END = DATE '9999-12-31'
AND T2.TRANSACTION_END = DATE '9999-12-31'
AND T1.ROWID != T2.ROWID;
IF (ROWCOUNT>0) THEN
RAISE_APPLICATION_ERROR(-20001, 'BITEMPORAL INTEGRITY TRIGGER CHECK : ACTIVE VALID_TIME OVERLAP');
END IF;
SELECT COUNT(*) INTO ROWCOUNT
FROM SOME_TABLE S, SOME_TABLE T2
WHERE S.VALID_END < T2.VALID_START
AND S.PK_COLUMN1 = T2.PK_COLUMN1
AND S.PK_COLUMN2 = T2.PK_COLUMN2
AND S.TRANSACTION_END = DATE '9999-12-31'
AND T2.TRANSACTION_END = DATE '9999-12-31'
AND NOT EXISTS (
SELECT *
FROM SOME_TABLE T3
WHERE T3.PK_COLUMN1 = S.PK_COLUMN1
AND T3.PK_COLUMN2 = S.PK_COLUMN2
AND (((T3.VALID_START <= S.VALID_END)
AND (S.VALID_END < T3.VALID_END))
OR ((T3.VALID_START < T2.VALID_START)
AND (T2.VALID_START <= T3.VALID_END)))
AND T3.TRANSACTION_END = DATE '9999-12-31');
IF (ROWCOUNT>0) THEN
RAISE_APPLICATION_ERROR(-20001, 'BITEMPORAL TRIGGER CHECK : ACTIVE VALID_TIME CONTINUITY VIOLATED (GAPS)');
END IF;
END;
PK_COLUMN(s)
Приготовление естественных ключей, отдых должен быть очевидным.
Вопросы следующие:
Я включил все возможные сценарии? Есть ли дополнительный контракт, который я забыл проверить?
Дополнительный вопрос, можете ли вы порекомендовать какую-либо другую солидную книгу / ресурс по двухвременным архитектурам данных?
// Добавлены еще несколько тегов, для большей досягаемости...
Любые комментарии, предложения, конструктивная критика приветствуется.
Заранее спасибо,
Мэтт.