4

是否有任何有用的工具或技巧可以自动(或快速)为 MySQL 中的给定表创建历史表 + 触发器?到目前为止,我已经遇到过这个工具,但它已经有一段时间没有更新了。如果相关,我使用 MySQL Workbench 的“模型”工具来构建我的数据库模型,然后将它们与我的本地数据库同步。

我想要的是能够为表提供创建脚本,并让该工具神奇地为历史表和触发器创建脚本,以便在插入/更新/删除时插入这些历史表。例如,如果我有一个foo包含复合 PK ab、 外键cd和 属性的表ef它将为foo_history具有复合 PK abrevisionNumcde、 、 、 、 、 的历史表生成创建脚本,fcd- 加上可能指示的列操作的时间以及是否是 INSERT/UPDATE/DELETE。

如果它不存在,我很乐意制作这样的脚本并分享它,但如果它存在,我不想重新发明轮子。如果没有,您认为其他人使用这样的脚本最方便的格式是什么/您如何将其融入您的模型开发工作流程?

4

2 回答 2

2

我为自己创建了这个小怪物 php 脚本,它从一些速记 txt 文件生成 SQL DDL,现在它可以生成历史表及其CREATE TRIGGER语句。

http://simpleddl.coolpage.biz/

示例来源:

// ZZZ means "Create History Table + Triggers"
// you can try editing it live at the link above

!DROP
= ID id P AI

person ZZZ
  ID
  name _
  N mother_id -> person
  N father_id -> person
  !FK mother_id, father_id -> family

family ZZZ
  P female_id -> person
  P male_id   -> person

生成的 SQL DDL:

DROP   TABLE IF     EXISTS person;
CREATE TABLE IF NOT EXISTS person (
   id         INT NOT NULL AUTO_INCREMENT,
   name       VARCHAR(255) NOT NULL,
   mother_id  INT NULL,
   father_id  INT NULL,
   PRIMARY KEY ( id ),
   FOREIGN KEY ( mother_id ) REFERENCES person( id ),
   FOREIGN KEY ( father_id ) REFERENCES person( id ),
   FOREIGN KEY ( mother_id, father_id ) REFERENCES family( female_id, male_id )
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

DROP   TABLE IF     EXISTS family;
CREATE TABLE IF NOT EXISTS family (
   female_id  INT NOT NULL,
   male_id    INT NOT NULL,
   PRIMARY KEY ( female_id, male_id ),
   FOREIGN KEY ( female_id ) REFERENCES person( id ),
   FOREIGN KEY ( male_id ) REFERENCES person( id )
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP   TABLE IF     EXISTS zz_person;
CREATE TABLE IF NOT EXISTS zz_person (
   id         INT NOT NULL,
   name       VARCHAR(255) NOT NULL,
   mother_id  INT NULL,
   father_id  INT NULL,
   _zz_id     INT NOT NULL AUTO_INCREMENT,
   _zz_op     CHAR(1) NOT NULL,
   _zz_date   datetime NOT NULL,
   PRIMARY KEY ( _zz_id ),
   INDEX P ( id ),
   INDEX ( father_id, mother_id ),
   INDEX ( _zz_op ),
   INDEX ( _zz_date )
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

DROP   TABLE IF     EXISTS zz_family;
CREATE TABLE IF NOT EXISTS zz_family (
   female_id  INT NOT NULL,
   male_id    INT NOT NULL,
   _zz_id     INT NOT NULL AUTO_INCREMENT,
   _zz_op     CHAR(1) NOT NULL,
   _zz_date   datetime NOT NULL,
   PRIMARY KEY ( _zz_id ),
   INDEX P ( male_id, female_id ),
   INDEX ( _zz_op ),
   INDEX ( _zz_date )
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;


DROP   TRIGGER IF EXISTS INSERT_ON_person;
CREATE TRIGGER           INSERT_ON_person
                   AFTER INSERT ON person
FOR EACH ROW INSERT INTO
zz_person (     id,     name,     mother_id,     father_id, _zz_date, _zz_op )
   VALUES ( NEW.id, NEW.name, NEW.mother_id, NEW.father_id,  NOW()  ,  'i'   );

DROP   TRIGGER IF EXISTS UPDATE_ON_person;
CREATE TRIGGER           UPDATE_ON_person
                   AFTER UPDATE ON person
FOR EACH ROW INSERT INTO
zz_person (     id,     name,     mother_id,     father_id, _zz_date, _zz_op )
   VALUES ( NEW.id, NEW.name, NEW.mother_id, NEW.father_id,  NOW()  ,  'u'   );

DROP   TRIGGER IF EXISTS DELETE_ON_person;
CREATE TRIGGER           DELETE_ON_person
                   AFTER DELETE ON person
FOR EACH ROW INSERT INTO
zz_person (     id,     name,     mother_id,     father_id, _zz_date, _zz_op )
   VALUES ( OLD.id, OLD.name, OLD.mother_id, OLD.father_id,  NOW()  ,  'd'   );

DROP   TRIGGER IF EXISTS INSERT_ON_family;
CREATE TRIGGER           INSERT_ON_family
                   AFTER INSERT ON family
FOR EACH ROW INSERT INTO
zz_family (     female_id,     male_id, _zz_date, _zz_op )
   VALUES ( NEW.female_id, NEW.male_id,  NOW()  ,  'i'   );

DROP   TRIGGER IF EXISTS UPDATE_ON_family;
CREATE TRIGGER           UPDATE_ON_family
                   AFTER UPDATE ON family
FOR EACH ROW INSERT INTO
zz_family (     female_id,     male_id, _zz_date, _zz_op )
   VALUES ( NEW.female_id, NEW.male_id,  NOW()  ,  'u'   );

DROP   TRIGGER IF EXISTS DELETE_ON_family;
CREATE TRIGGER           DELETE_ON_family
                   AFTER DELETE ON family
FOR EACH ROW INSERT INTO
zz_family (     female_id,     male_id, _zz_date, _zz_op )
   VALUES ( OLD.female_id, OLD.male_id,  NOW()  ,  'd'   );

测试小提琴:

http://sqlfiddle.com/#!2/d05e6/1

于 2013-02-23T20:43:57.983 回答
0

我只想编写一个工具来查询表的模式,然后生成脚本以手动运行。只是一个您喜欢的语言的简单代码生成器。

作为注释,我建议编写脚本来删除您编写的对象。只是帮助清理,以防你在前几次弄错了。

于 2013-02-22T22:58:15.450 回答