保持页面更改历史记录。有点像SO做修订

时间:2010-08-14 00:05:27

标签: mysql database version-control revision entity-attribute-value

我有一个CMS系统,可以跨表格存储数据:

Entries Table
+----+-------+------+--------+--------+
| id | title | text | index1 | index2 |
+----+-------+------+--------+--------+

Entries META Table
+----+----------+-------+-------+
| id | entry_id | value | param |
+----+----------+-------+-------+

Files Table
+----+----------+----------+
| id | entry_id | filename |
+----+----------+----------+

Entries-to-Tags Table
+----+----------+--------+
| id | entry_id | tag_id |
+----+----------+--------+

Tags Table
+----+-----+
| id | tag |
+----+-----+

我正在尝试实施修订系统,有点像SO。如果我只是为Entries Table执行此操作,我计划在另一个表中保留对该表的所有更改的副本。因为我必须为至少4个表做这个(TAGS表不需要修改),这似乎不是一个优雅的解决方案。

你们会怎么做?

请注意 元数据表 是在EAV (entity-attribute-value)建模的。

提前谢谢。

3 个答案:

答案 0 :(得分:8)

您好我正在解决类似问题的解决方案,我通过将我的表分成两个,一个控制表和一个数据表来解决它。控制表将包含主键和数据表的引用,数据表将包含自动增量修订密钥,控制表的主键作为外键。

以条目表为例

Entries Table
+----+-------+------+--------+--------+
| id | title | text | index1 | index2 |
+----+-------+------+--------+--------+

变为

entries             entries_data
+----+----------+   +----------+----+--------+------+--------+--------+
| id | revision |   | revision | id |  title | text | index1 | index2 |
+----+----------+   +----------+----+--------+------+--------+--------+

查询

select * from entries join entries_data on entries.revision = entries_data.revision;

而不是更新entries_data表,而是使用insert语句,然后使用条目表的新版本更新条目表的修订版。

此系统的优点是只需更改条目表中的revision属性即可移至不同的修订版。缺点是您需要更新查询。我目前正在将其集成到ORM层中,因此开发人员无需担心编写SQL。我想要的另一个想法是有一个集中的修订表,所有数据表都使用。这将允许您使用单个修订号描述数据库的状态,类似于颠覆修订号的工作方式。

答案 1 :(得分:6)

看一下这个问题:How to version control a record in a database

为什么每个表都没有单独的history_table(根据链接问题的接受答案)?它只是原始表的PK和修订号的复合主键。毕竟,你仍然需要将数据存储在某个地方。

答案 2 :(得分:1)

对于我们的一个项目,我们采用以下方式:

Entries Table
+----+-----------+---------+
| id | date_from | date_to |
+----+--------_--+---------+

EntryProperties Table
+----------+-----------+-------+------+--------+--------+
| entry_id | date_from | title | text | index1 | index2 |
+----------+-----------+-------+------+--------+--------+

非常复杂,仍然可以跟踪完整对象的生命周期。因此,对于我们要查询的活动实体:

SELECT 
entry_id, title, text, index1, index2
FROM
Entities INNER JOIN EntityProperties
ON Entities.id = EntityProperties.entity_id
AND Entities.date_to IS NULL
AND EntityProperties.date_to IS NULL

唯一的问题是实体被删除的情况(所以我们在那里放了一个date_to),然后由admin恢复。使用给定的方案,无法跟踪这种技巧。

这样的任何尝试的总体缺点是显而易见的 - 你要编写大量的TSQL,其中非版本化的数据库将用于选择A连接B 之类的东西。