需要跟踪对数据库中对象所做的更改。
琐碎的实现将是使用镜像表来获取由数据库内部或应用程序内部的触发器插入的记录,但这会影响性能,并且随着时间的推移,镜像数据库变得庞大,并且当原始表必须被更改时,维护时间基本上会翻倍(镜像表需要反映出这种变化)。
由于我最大的要求是对数据库和应用程序性能的影响最小,我目前的首选是将更改转储到syslog-ng over udp并将它们存储在纯文本文件中。
在所有更改日志都不会被频繁访问之后,所以甚至可以随着时间的推移将其归档。但很明显,通过这样的设置实际访问数据非常棘手。
所以我想我的问题是 - 是否已经有一个系统至少部分满足了我的需求?完美匹配将是UDP访问的无模式附加数据库系统,可以自动归档数据(或至少执行此操作所需的最少量配置)或插入性能的非常缓慢的降级。 MongoDB的? CouchDB的? YourDB?
答案 0 :(得分:3)
嗯,有很多方法可以解决这个问题。我对MongoDB最熟悉,因此会倾向于这个方向。一般来说,我认为它将满足您对性能的需求,并且使用副本集,读取来自奴隶可能是采取的方法。但是,版本控制不是内置的。您可以在这里看到使用Mongoid :: Versioning进行版本控制的一种方法:
Mongoid::Versioning - how to check previous versions?
您提到的其他解决方案可能有更好的原生支持,但我不能说。希望这至少可以为您提供有关MongoDB方面的一些指示。
答案 1 :(得分:1)
它跟踪变化的历史,例如什么,何时,由谁以及版本。它还提供了配置选项
答案 2 :(得分:1)
RavenDB本机具有此功能(但可能太年轻,因为NoSQL数据库可满足生产需求 - 当然由您决定)
http://ravendb.net/docs/server/bundles/versioning
如果您想使用MongoDB,可在此thread
中提出两种实施策略 Strategy 1: embed history
不会影响您的写作效果,如果您调整代码以避免在没有必要的情况下返回历史记录,则会读取,但是您对一个文档有16Mb的限制(可能对您有效阻止)。 Strategy 2: write history to separate collection
需要(明显地)两个操作。我同意在那里说这些(或组合)是MongoDB中可用的策略。
CouchDB在内部使用MVCC方法(你可以按照建议here使用它),但在SO中这种方法是debated。 this topic上有一个问题,建议的解决方案类似于上面针对MongoDB描述的嵌入式策略(所以你应该选择你喜欢的那个)。
答案 3 :(得分:1)
出于简单目的(MySQL!),只需对要保留记录的表执行AFTER UPDATE触发器。
例如,对于带有字段的桌车
carId(主键) 颜色 生产厂家 模型
使用字段创建表'cars_history'(或相同名称): carId 领域 OLD_VALUE NEW_VALUE
并添加一个AFTER UPDATE触发器,如下所示:
delimiter //
CREATE TRIGGER trigger_changes
AFTER UPDATE ON cars
FOR EACH ROW
BEGIN
IF OLD.manufacturer <> NEW.manufacturer THEN
INSERT INTO cars_history
( carId, field, old_value, new_value)
VALUES
(OLD.carId, 'manufacturer', OLD.manufacturer, NEW.manufacturer);
ELSE IF OLD.color <> NEW.color THEN
...
END IF;
END;//
delimiter ;
未经测试,因此可能包含语法错误:)希望无论如何都有帮助!
答案 4 :(得分:0)
SQLite怎么样?每个数据库都是一个独立的文件,您可以在归档时轻松地重命名和移动。如果文件被重命名或自动移动,则在下一次插入时创建其他文件。
关于SQLite的唯一问题是并发写入,它需要阻止文件进行写入。它每秒可以执行大约60个事务,但是您可以在一个事务中执行数千个插入(请参阅doc)。
答案 5 :(得分:0)
我想知道这是否是您正在寻找的解决方案类型: http://www.tonymarston.net/php-mysql/auditlog.html
它似乎是一个非常简单,优雅的解决方案,占用的数据量很小,我希望它对插入时间的影响也很小。