数据库 - 单表中的数据版本控制

时间:2011-08-26 13:23:38

标签: php database versioning

我正在开发一个具有一些版本控制功能的CMS。它基于MySQL Db。

这个想法是向公共网站访问者显示数据的“特定版本”,并向后台用户预览“最新版本”。发布内容只是意味着将“特定修订版”设置为等于最新修订版(并且可能删除旧修订版的数据)。

我已经阅读了一些Q&关于SO的主题,大多数人都建议在同一个表中保留“旧”和“新”行是不好的。但是,由于我需要连接表,所有这些都是“版本化的”,在不同的表中拆分旧的和新的也不理想(应用程序应该如何知道来自一个修订版的“内容”是旧的还是新的,因此是是否在“_history”表中找到了?)。

所以我决定只为每个“内容类型”使用一个表。

我使用的设计: 每个表都包含一个“revision INT NOT NULL”列(主键的一部分,以及一个ID列)。

修改某些内容意味着插入一个包含修改后的值的新行,一个递增的修订版,但ID相同。

插入内容意味着插入一个具有递增ID和递增版本的新行。

删除某些内容意味着插入一个具有相同ID,增量版本和“thumbstone”标志设置为“true”的空行。

示例:有页面并且有“视图”(“视图不在MVC意义上,视图在应用程序特定含义中)。”视图“是版本化的。一个页面有很多视图。 这是(视图)的一部分。

CREATE TABLE `_views` (
  `_id` int(11) NOT NULL,
  `_rev` int(11) NOT NULL,
  `_ts` BIT(1) DEFAULT b'0',
  `page` int(11) NOT NULL,
  `order` int(11) NOT NULL,
  PRIMARY KEY (`_id`,`_rev`)
)

我需要按照“订单”指定的顺序选择页面包含的所有视图,最多为“特定版本”。

此查询有效:

SELECT * FROM (
 SELECT *
 FROM `_views`
 WHERE `page` = :page
 AND `_rev` <= :revision
 ORDER BY `_rev` DESC
) AS `all`
GROUP BY `_id`
HAVING `_ts` = 0
ORDER BY `order`

子查询选择页面的所有视图,这些视图曾被“发布”(哪个版本小于或等于“已发布”版本)。外部查询将它们分组为最新版本,删除具有thumbstone的组并按应用程序特定条件对它们进行排序。

因为CMS的可伸缩性和性能至关重要,是否有比子查询更好,更优雅的方式?

......或者我应该专注于缓存?

1 个答案:

答案 0 :(得分:2)

使用子查询来确定当前版本不是最好的方法;你真的不想去那里。

更简单的方法是添加一个标志,告诉您最新版本:

   `_rev` int(11) NOT NULL,
   `_current` BIT(1),

这需要手动更新,以便在添加新修订或更改_current标志时设置_ts标志。但至少可以避免在每个页面显示上执行子查询

作为替代方案,您仍然可以将数据拆分为_current_history表。然后,您只需为这些情况创建一个视图,以便再次加入结果集:

 CREATE VIEW pages_all AS
      SELECT * FROM pages_current
      UNION ALL SELECT * FROM pages_history

同样,如果您需要经常对它们进行分组,则可以创建所有活动(非缩略图)修订的子表。虽然这会导致比__urrent标志更多的手动微观管理,或仅仅是对_history表的看法。