SQL Store历史数据

时间:2018-11-20 08:35:47

标签: sql sqlanywhere

我们要创建一个通用日志文件,用于存储数据库中任何表的历史数据。为此,我们创建了表格

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是通用行ID
  • VID是用于更改值的update语句的ID(如果已更新了几列)
  • TABLE_NAME包含更新后的表的名称
  • COLUMN_NAME包含已更改列的名称
  • COLUMN_VALUE包含已更改列的旧值
  • KEY_VALUES包含TABLE_NAME的主键作为Blob,以标识已更改的行
  • 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_VALUESKARECURRENCEUID的旧值。表Calendar_Recurrence_Date将存储KEY_VALUES + KARECURRENCEUID的{​​{1}}的旧值。

要读取存储的值,我们必须选择从KASEQUENCE开始的所有KEY_VALUES,这将减慢查询速度并可能导致选择错误的数据。 在生产中,此场景有13个关联表

是否有更好的通用方式存储历史记录?

我们的DBMS(Sql Anyhwere)不支持像Microsoft SQL Server中的“更改数据捕获”之类的功能。

0 个答案:

没有答案