簡體   English   中英

具有InnoDB版本控制行的MySQL

[英]MySQL with InnoDB revision control rows

我想要一種控制/跟蹤行修訂的方法。 我正在嘗試找到針對此問題的最佳解決方案。

首先想到的是擁有一個表,該表具有一個ID,用於標識行和版本號的ID。 組合的ID將是主鍵。 因此示例數據可能如下所示:

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

如何使用這種行為創建表? 還是有更好的解決方案?

我喜歡InnoDB,因為它在MySQL 5.6+中支持事務,外鍵和全文。

我知道通過插入數據來“強制”這種行為是可能的,但是我想知道是否有一種方法可以讓表格自動執行此操作。

考慮表結構:

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

posts表在哪里跟蹤有關該帖子及其當前修訂的非版本信息,而revisions通過鏈接回父帖子的鏈接來跟蹤該帖子文本的每個版本。 由於FK的循環約束,您需要在事務中添加新的帖子插入。

有了它,您應該能夠輕松地添加,刪除,跟蹤,回滾和預覽帖子的修訂。

編輯:

是的,因為密鑰設置為AUTO_INCREMENT ,所以封閉事務並不會完全有幫助,因此您需要使用LAST_INSERT_ID()和一些臨時NULL索引重新使用PHP。

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`);

然后:

$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");

如果我對您的理解正確,並且該表未收到大量更新/刪除,則可以考慮設置觸發器,例如:

DELIMITER $$
CREATE TRIGGER t_table_update BEFORE UPDATE ON table_name
FOR EACH ROW
    INSERT INTO table_name_revisions (item_id, data, timestamp) 
        VALUES(OLD.id, OLD.data, NOW());
END$$
DELIMITER ;

有關更多信息,請參見觸發器語法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM