我正在开发具有某些版本控制功能的 CMS。它基于 MySQL Db。
这个想法是向公共(public)网站访问者展示数据的“特定修订”,并向后台用户展示“最新修订”的预览。发布一些东西只是意味着将“特定版本”设置为最新版本(并且可能删除旧版本的数据)。
我读过一些关于 SO 主题的问答,其中大多数建议在同一个表中保存“旧”行和"new"行是不好的。但是,由于我需要加入表格,所有表格都“版本化”,在不同的表格中拆分旧的和新的也不理想(应用程序应该如何知道一个修订版的“内容”是旧的还是新的,因此是是否在“_history”表中找到?)。
所以我决定只为每个“内容类型”使用一个表格。
我使用的设计: 每个表都有一个“revision INT NOT NULL”列(主键的一部分,以及一个 ID 列)。
修改某些内容意味着插入一个新行,其中包含修改后的值、递增的修订版,但 ID 相同。
插入内容意味着插入一个 ID 递增且版本递增的新行。
删除某些内容意味着插入一个具有相同 ID、增量修订和设置为“true”的“thumbstone”标志的空行。
示例:有页面和“ View ”(“不是 MVC 意义上的 View ,应用程序特定含义中的 View ”)。“ View ”是版本化的。一个页面有多个 View 。 这是(部分)“ View ”。
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”指定的顺序选择页面包含的所有 View ,直至“特定修订”。
此查询有效:
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`
子查询选择页面的所有 View ,这些 View 曾经是“已发布”(修订版小于或等于“已发布”修订版)。外部查询将它们分组到它们的 最新版本,删除具有拇指石的组并按应用程序特定标准对它们进行排序。
既然 CMS 的可扩展性和性能至关重要,难道没有比子查询更好、更优雅的方法吗?
...或者我应该只专注于缓存?
最佳答案
使用子查询来确定当前修订不是最好的方法;你真的不想去那里。
一个更简单的方法是添加一个标志,告诉您最新的修订:
`_rev` int(11) NOT NULL,
`_current` BIT(1),
每当添加新修订版或更改 _ts
标志时,这需要手动更新以设置 _current
标志。但至少这避免了在每个页面显示上执行子查询。
作为替代方案,您仍然可以将数据拆分到 _current
和 _history
表中。如果您需要再次加入结果集,那么您只需为这两种情况创建一个 View :
CREATE VIEW pages_all AS
SELECT * FROM pages_current
UNION ALL SELECT * FROM pages_history
同样,如果您需要经常对它们进行分组,则可以为所有事件(非拇指删除)修订创建一个子表。尽管与 _current 标志或只是查看 _history 表相比,这会导致更多的手动微观管理。
关于php - 数据库 - 单个表中的数据版本控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7205295/