Хранилище SQL исторических данных - PullRequest
0 голосов
/ 20 ноября 2018

Мы хотим создать общий файл журнала для хранения исторических данных любой таблицы в нашей базе данных.Для этого мы создали таблицу

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.

...