我正在开发一个具有一些版本控制功能的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的可伸缩性和性能至关重要,是否有比子查询更好,更优雅的方式?
......或者我应该专注于缓存?
答案 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表的看法。