我有一个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)建模的。
提前谢谢。
答案 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 之类的东西。