【发布时间】:2011-08-26 13:23:38
【问题描述】:
我正在开发具有一些版本控制功能的 CMS。它基于 MySQL Db。
这个想法是向公共网站访问者展示数据的“特定修订版”,并向后台用户展示“最新修订版”的预览。发布某些东西只是意味着将“某些修订”设置为等于最新的(并且可能删除旧修订的数据)。
我已经阅读了一些关于 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`)
)
我需要按照“order”指定的顺序选择页面包含的所有视图,直到“某些修订版”。
此查询有效:
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`
子查询选择页面的所有视图,这些视图曾经“发布”(哪个版本小于或等于“发布”版本)。外部查询将它们分组到他们的最新修订版,删除具有拇指石的组并按应用程序特定标准对它们进行排序。
既然 CMS 的可扩展性和性能至关重要,难道没有比子查询更好、更优雅的方法吗?
...还是我应该只专注于缓存?
【问题讨论】:
-
“拇指石”这件事又是什么目的?
-
这是“墓碑”的另一种拼写。这是一个标志,标志着某事被“删除”(以此类推,已死)。所以可以通过删除这个“删除修订”轻松恢复
标签: php database versioning