[英]MySQL with InnoDB revision control rows
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. 首先想到的是拥有一个表,该表具有一个ID,用于标识行和版本号的ID。 The combined ids would be the primary key. 组合的ID将是主键。 so example data might look like this: 因此示例数据可能如下所示:
1, 0, "original post"
1, 1, "modified post"
1, 2, "modified again post"
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+. 我喜欢InnoDB,因为它在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. 我知道通过插入数据来“强制”这种行为是可能的,但是我想知道是否有一种方法可以让表格自动执行此操作。
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. posts
表在哪里跟踪有关该帖子及其当前修订的非版本信息,而revisions
通过链接回父帖子的链接来跟踪该帖子文本的每个版本。 Because of the circular FK constraints you'd need to enclose new post insertions in a transaction. 由于FK的循环约束,您需要在事务中添加新的帖子插入。
With this you should be able to easily add, remove, track, roll back, and preview revisions to your posts. 有了它,您应该能够轻松地添加,删除,跟踪,回滚和预览帖子的修订。
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. 是的,因为密钥设置为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`);
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");
If I've understood you correctly and the table doesn't receive large numbers of updates/deletes then you could look at setting a trigger such as: 如果我对您的理解正确,并且该表未收到大量更新/删除,则可以考虑设置触发器,例如:
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 ;
See trigger syntax for more information 有关更多信息,请参见触发器语法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.