Мы хотим создать общий файл журнала для хранения исторических данных любой таблицы в нашей базе данных.Для этого мы создали таблицу
CREATE TABLE "COMMON_DATA_LOG" (
"UID" UNIQUEIDENTIFIER NOT NULL DEFAULT "NEWID"(),
"VID" UNIQUEIDENTIFIER NOT NULL,
"TABLE_NAME" VARCHAR(128) NOT NULL,
"COLUMN_NAME" VARCHAR(128) NOT NULL,
"COLUMN_VALUE" LONG BINARY NULL,
"KEY_VALUES" LONG BINARY NOT NULL,
"MODIFIED" TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
"MODIFIED_USER" VARCHAR(128) NOT NULL DEFAULT CURRENT USER,
PRIMARY KEY ( "UID" ASC )) IN "system";
UID
- это общий идентификатор строки VID
- это идентификатор оператора обновления, который изменил значения, если несколько столбцов имеютбыли обновления TABLE_NAME
содержит имя обновленной таблицы COLUMN_NAME
содержит имя измененного столбца COLUMN_VALUE
содержит старое значение измененногостолбец KEY_VALUES
содержит первичный ключ TABLE_NAME
в виде большого двоичного объекта для идентификации измененной строки MODIFIED
простая отметка времени MODIFIED_USER
пользователя sql, который изменилсяданные
Мы используем триггеры в наших таблицах для заполнения этой таблицы журнала, которые проверяют, изменился ли столбец, и сохраняют старое значение в таблице COMMON_DATA_LOG
.Это прекрасно работает в среде, где таблицы не имеют внешних ключей или простых ассоциаций 1-1.
Проблема заключается в таблицах, которые используют 1-n и комбинированные первичные ключи.Чтение зарегистрированных значений для связанных таблиц довольно трудное и медленное.
Предположим, что следующие таблицы
CREATE TABLE "Calendar_Recurrence" (
"KARECURRENCEUID" UNIQUEIDENTIFIER NOT NULL,
"KAFREQ" VARCHAR(50) NOT NULL DEFAULT 'DAILY',
"KAUNTIL" INTEGER NULL,
"KAINTERVAL" INTEGER NOT NULL DEFAULT 1,
"KABYDAY" VARCHAR(50) NULL,
"KABYMONTHDAY" INTEGER NULL,
"KABYMONTH" INTEGER NULL, PRIMARY KEY ( "KARECURRENCEUID" ASC )) IN "system";
CREATE TABLE "Calendar_Recurrence_Date" (
"KARECURRENCEUID" UNIQUEIDENTIFIER NOT NULL,
"KASEQUENCE" INTEGER NOT NULL,
"KASTARTTIME" "datetime" NOT NULL,
"KAENDTIME" "datetime" NOT NULL, PRIMARY KEY ( "KASEQUENCE" ASC, "KARECURRENCEUID" ASC )) IN "system";
Связаны с
ALTER TABLE "Calendar_Recurrence_Date" ADD CONSTRAINT "Calendar_Recurrence" NOT NULL FOREIGN KEY ( "KARECURRENCEUID" ASC ) REFERENCES "Calendar_Recurrence" ( "KARECURRENCEUID" );
Если мы следуем нашей таблице журнала,Таблица Calendar_Recurrence
будет хранить старые значения с KEY_VALUES
равным KARECURRENCEUID
.Таблица Calendar_Recurrence_Date
будет хранить старые значения с KEY_VALUES
из KARECURRENCEUID
+ KASEQUENCE
.
Чтобы прочитать сохраненные значения, нам нужно будет выбрать все KEY_VALUES
, начиная с KARECURRENCEUID
,это замедлит запросы и может привести к неправильному выбору данных. В производстве у нас есть 13 связанных таблиц для этого сценария .
Есть ли лучший способ для хранения истории общим способом?
Наша СУБД (Sql Anyhwere) не поддерживает такие функции, как сбор данных изменений, как в Microsoft SQL Server.