4

Are there any useful tools or tricks to automatically (or quickly) create history tables + triggers for a given table in MySQL? I've come across this tool so far, but it hasn't been updated in a while. If it's relevant, I use MySQL Workbench's "Model" tool to build my database models and then synchronize those with my local database.

What I would like is to be able to provide create scripts for tables and have the tool magically spit out create scripts for history tables and triggers to insert into those history tables on insert/update/delete. For example, if I have table foo with composite PK a, b, foreign keys c, d, and attributes e, f, it would produce create scripts for a history table foo_history with composite PK a, b, revisionNum, and c, d, e, f, removing relations from c and d - plus perhaps a column indicating the time of the operation and whether it was an INSERT/UPDATE/DELETE.

I would be happy to produce such a script and share it if it does not already exist, but I don't want to reinvent the wheel if it does. If it does not, what do you think would be the most convenient format for others to consume such a script / how would you fit it into your model development workflow?

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 に答える