如何在MySQL中实现Temporal Upward Compatibility?

时间:2012-02-25 17:49:41

标签: mysql database database-design

我想使用mysql实现一个时态数据库。我发现BerekelyDB Engine不支持当前的MySQL版本。我想存储数据并查询历史记录。 (不想删除任何数据)。比如说桌子stundet。

Student_ID      Student_Name   Class   Added_Date               Deleted_Date 
1004            ABC             19   2011-02-03:18-24         2011-04-03:20-24
1004            ABC_D           19   2011-04-03:20-24         null

这是我想要的示例表。当我更改一些细节时,将添加一个deleted_datetime标记,并添加一个完整的新记录。删除记录时,只会添加Deleted_Date

所以我必须编写一个完整的库,或者是否有任何特定的库或数据库实现来支持我的问题?...

顺便说一下,我发现了这个http://www.cs.arizona.edu/projects/tau/tbdb/,但似乎只适用于旧版本。

1 个答案:

答案 0 :(得分:2)

将非时态表升级到时态表时,可以为旧应用程序实现兼容性,即为时态表创建非时间视图。该视图将时态数据减少为当前有效数据。对于这样的视图,您可以创建所谓的而不是触发器,这些触发器在时态表上执行正确的操作。

不幸的是,这不适用于MySQL,因为MySQL的功能是有限的。这意味着您有两种可能的解决方案:

  • 将数据迁移到功能更强大的数据库中。
  • 修改应用程序。

以下示例显示了第一种替代方案的可能解决方案。我用Oracle 10gR2测试了这个例子。

为时态数据创建表。当前值是 结束为NULL的值。独特的约束 防止表包含多个当前值。该 table没有主键,因为id不是唯一的 时态表,但仅限于遗留视图。

CREATE TABLE temporal (
  id         NUMBER NOT NULL,
  starting   TIMESTAMP NOT NULL,
  ending     TIMESTAMP,
  attribute  CHAR(20),
  UNIQUE (id, ending));

为旧版应用程序创建一个视图。

CREATE VIEW legacy (id, attribute) AS
  SELECT id, attribute FROM temporal WHERE ending IS NULL;

为执行的旧表创建“代替”触发器 正确插入到时态表中。插入到 遗留表也是时态表中的插入。

CREATE TRIGGER legacy_insert
INSTEAD OF INSERT ON legacy
FOR EACH ROW
BEGIN
  INSERT INTO temporal (id, starting, ending, attribute)
  VALUES (:NEW.id, CURRENT_TIMESTAMP, NULL, :NEW.attribute);
END;

为旧表的更新创建“代替”触发器。 旧表的更新是更新和插入 时间表。当前值将更新并更新 值插入一个新行。

CREATE TRIGGER legacy_update
INSTEAD OF UPDATE ON legacy
FOR EACH ROW
BEGIN
  UPDATE temporal SET ending = CURRENT_TIMESTAMP WHERE id = :NEW.id;
  INSERT INTO temporal (id, starting, ending, attribute)
  VALUES (:NEW.id, CURRENT_TIMESTAMP, NULL, :NEW.attribute);
END;

为删除属性创建“代替”触发器 遗留表。删除遗留表是对该表的更新 时间表。

CREATE TRIGGER legacy_delete
INSTEAD OF DELETE ON legacy
FOR EACH ROW
BEGIN
  UPDATE temporal SET ending = CURRENT_TIMESTAMP 
  WHERE id = :OLD.id AND ending IS NULL;
END;

尝试插入。

INSERT INTO legacy (id, attribute) VALUES (1, 'a');
SELECT * FROM legacy;
SELECT * FROM temporal;

尝试更新。

UPDATE legacy SET attribute = 'A' WHERE id = 1;
SELECT * FROM legacy;
SELECT * FROM temporal;

尝试删除。

DELETE FROM legacy WHERE id = 1;
SELECT * FROM legacy;
SELECT * FROM temporal;