duanluwei9374 2013-11-13 19:10
浏览 77

MySQL与InnoDB版本控制行

I would like to have a way of controlling/tracking revisions of rows. I am trying to find the best solution for this problem.

The first thing that comes to mind is to have a table with a id to identify the row and and id for the revision number. The combined ids would be the primary key. so example data might look like this:

1, 0, "original post" 1, 1, "modified post" 1, 2, "modified again post"

How can I create a table with this behavior? or is there a better solution to do this?

I like InnoDB since it supports transactions, foreign keys and full text in MySQL 5.6+.

I know its possible to "force" this behavior by how I insert the data but I'm wondering if there is a way to have the table do this automatically.

  • 写回答

2条回答 默认 最新

  • dongyong5912 2013-11-13 19:26
    关注

    Consider table structure:

    TABLE posts
      post_id INT AUTO_INCREMENT PK
      cur_rev_id INT FK(revisions.rev_id)
    
    TABLE revisions
      rev_id INT AUTO_INCREMENT PK
      orig_post INT FK(posts.post_id)
      post_text VARCHAR
    

    Where the posts table tracks non-versioned information about the post and its current revision, and revisions tracks each version of the post text with a link back to the parent post. Because of the circular FK constraints you'd need to enclose new post insertions in a transaction.

    With this you should be able to easily add, remove, track, roll back, and preview revisions to your posts.

    Edit:

    Yeah, enclosing in a transaction won't exactly help since the keys are set to AUTO_INCREMENT, so you need to dip back in to PHP with LAST_INSERT_ID() and some temporarily NULL indexes.

    CREATE TABLE `posts` (
        `post_id` INT(10) NOT NULL AUTO_INCREMENT,
        `cur_rev_id` INT(10) NULL DEFAULT NULL,
        `post_title` VARCHAR(50) NULL DEFAULT NULL,
        PRIMARY KEY (`post_id`),
        INDEX `FK_posts_revisions` (`cur_rev_id`),
    ) ENGINE=InnoDB
    
    CREATE TABLE `revisions` (
        `rev_id` INT(10) NOT NULL AUTO_INCREMENT,
        `orig_post` INT(10) NULL DEFAULT NULL,
        `post_text` VARCHAR(32000) NULL DEFAULT NULL,
        PRIMARY KEY (`rev_id`),
        INDEX `FK_revisions_posts` (`orig_post`),
    ) ENGINE=InnoDB
    
    ALTER TABLE `posts`
        ADD CONSTRAINT `FK_posts_revisions` FOREIGN KEY (`cur_rev_id`) REFERENCES `revisions` (`rev_id`);
    ALTER TABLE `revisions`
        ADD CONSTRAINT `FK_revisions_posts` FOREIGN KEY (`orig_post`) REFERENCES `posts` (`post_id`);
    

    Then:

    $db_engine->query("INSERT INTO posts (cur_rev_id, post_title) VALUES (NULL, 'My post Title!')");
    $post_id = $db_engine->last_insert_id();
    
    $db_engine->query("INSERT INTO revisions (orig_post, post_text) VALUES($post_id, 'yadda yadda')");
    $rev_id = $db_engine->last_insert_id();
    
    $db_engine->query("UPDATE posts SET cur_rev_id = $rev_id WHERE post_id = $post_id");
    
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog