Language agnostic &引用;“差异化”;关系数据库中的对象

Language agnostic &引用;“差异化”;关系数据库中的对象,language-agnostic,oop,diff,Language Agnostic,Oop,Diff,我们的win32应用程序从MySQL关系数据库中多个表中的数据组装对象。对于此类对象,数据库中存储了多个修订 当存储某个内容的多个修订版本时,迟早您会问自己是否可以可视化两个修订版本之间的差异:)因此我的问题是:什么是“区分”两个这样的数据库对象的好方法? 您会在数据库级别进行比较吗?(听起来不是个好主意:级别太低,对模式太敏感) 你能比较一下这些物体吗? 您是否会编写一个“手动”比较两个对象的属性和字段的函数 您将如何存储差异?在单独的通用“TDiff”对象中 关于如何在用户界面中可视化这

我们的win32应用程序从MySQL关系数据库中多个表中的数据组装对象。对于此类对象,数据库中存储了多个修订

当存储某个内容的多个修订版本时,迟早您会问自己是否可以可视化两个修订版本之间的差异:)因此我的问题是:什么是“区分”两个这样的数据库对象的好方法?

  • 您会在数据库级别进行比较吗?(听起来不是个好主意:级别太低,对模式太敏感)
  • 你能比较一下这些物体吗?
    • 您是否会编写一个“手动”比较两个对象的属性和字段的函数
    • 您将如何存储差异?在单独的通用“TDiff”对象中
    • 关于如何在用户界面中可视化这些东西,有什么一般性的建议吗
建议,或者关于你自己的经历的故事,是非常受欢迎的;非常感谢

关于用例的额外信息(20090515) 作为对Antony评论的回复:此特定应用程序用于安排由教师团队管理的培训课程。教师的时间表存储在数据库的各个表中,并包含诸如“她哪天必须去哪里”、“她在团队中的同事是谁”等信息。这些信息分布在多个表中

偶尔,我们会“发布”时间表,这样老师们就可以在网页上看到了。每个“出版物”都是一个修订版,我们希望能够向用户(以及后来的老师)展示两个出版物之间的变化——如果有的话

希望这能让场景更具体一些:)

最后几句话
恩,赏金已经结束了,所以我接受了一个答案。如果有可能从我的代表身上多切几个100分,然后给其他一些答案,我会毫不犹豫地这样做。你们所有人的帮助都很好,我非常感激!~在No 20090519上,我已经研究过MysQL的很多次了。不幸的是,没有任何真正好的解决方案可用

我试过的一个工具是mysqldiff(www.mysqldiff.org)。mysqldiff是一个用PHP编写的工具,能够区分mysql模式。不幸的是,它并没有做一个伟大的工作很多时候

mysqlworkbench,MySQLs自己的sqlide提供了生成alter脚本的选项,我可以想象它是通过在内部执行某种diff操作来实现的

Aqua Data Studio是另一个能够比较模式并输出两者差异的工具。虽然adsdiff相当不错,但它不提供创建alter脚本的工具

若我自己写的话,我想我会编写能够比较两个表结构的代码。这样的代码可以调整为高度敏感(Ig,如果列顺序不同于下一个版本,这是一个差异)或更为中等敏感(例如列顺序不是主要问题,数据类型和长度很重要,索引和约束也很重要)

储藏室,我不确定。我将研究诸如Mercurial之类的版本控制系统如何存储其用于修订的差异信息,并使用该信息来详细说明适合DB的方法


最后,对于视觉输出,我建议您查看Aqua数据Stduio比较功能(您可以使用试用版来测试这一点…)。它的diff输出非常好。

这只是一个想法,但是您是否值得将正在比较的两个对象版本转换为某种文本格式,然后使用现有的diff程序(例如
diff
)比较这些文本对象?有很多很好的diff程序可以提供很好的视觉表现,等等

比如说

对象1的文本版本:

first_name: Harry
last_name: Lime
address: Wien
version: 0.1
对象2的文本版本:

first_name: Harry
last_name: Lime
address: Vienna
version: 0.2
差异可能类似于:

3,4c3,4
< address: Wien
< version: 0.1
---
> address: Vienna
> version: 0.2
3,4c3,4
<地址:维也纳
<版本:0.1
---
>地址:维也纳
>版本:0.2

我的应用程序dbscript比较存储过程中的分层数据(数据库模式),当然,存储过程必须将每个对象的每个字段/属性与其对应项进行比较。我猜你不会绕过这一步(除非你有一个通用的对象描述模型)


至于问题的UI部分,请看一看屏幕截图,了解它们之间的区别。

我会考虑对象的某种常见文本表示,并让文本与现有的差异化工具(如WinMerge)进行比较


我觉得没有必要自己发明diffing,因为我已经有很多很好的工具可以使用了。

在PostgreSQL中,我使用了一个与模式不同的表:

history_columns (
    column_id smallint primary key,
    column_name text not null,
    table_name text not null,
    unique (table_name, column_name)
);
create temporary sequence column_id_seq;
insert into history_columns
select nextval('column_id_seq'), column_name, table_name
    from information_schema.columns
    where
        table_name in ('table1','table2','table3')
        and table_schema=current_schema() and table_catalog=current_database();

create table history (
    column_id smallint not null references history_columns,
    id int not null,
    change_time timestamp with time zone not null
        constraint change_time_full_second -- only one change allowed per second
            check (date_trunc('second',change_time)=change_time),
    primary key (column_id,id,change_time),
    value text
);
在桌子上我用了这样一个触发器:

create or replace function save_history() returns trigger as
$$
    if (tg_op = 'DELETE') then
        insert into historia values (
            find_column_id('id',tg_relname), OLD.id,
            date_trunc('second',current_timestamp),
            OLD.id );
        [for each column_name] {
            if (char_length(OLD.column_name)>0) then
                insert into history values (
                    find_column_id(column_name,tg_relname), OLD.id,
                    OLD.change_time, OLD.column_name
                )
        }
    elsif (tg_op = 'UPDATE') then
        [for each column_name] {
            if (OLD.column_name is distinct from NEW.column_name) then
                insert into history values (
                    find_column_id(column_name,tg_relname), OLD.id,
                    OLD.change_time, OLD.column_name
                );
            end if;
        }
    end if;
$$ language plpgsql volatile;

create trigger save_history_table1
    before update or delete on table1
    for each row execute procedure save_history();
以Oracle为例

  • 使用dbms_元数据将有序对象导出为文本
  • 将有序表数据导出为CSV或查询格式
  • 制作大文本文件
  • 差异

假设一个类有5个已知属性—日期、时间、主题、大纲和位置。当我看我的时间表时,我最感兴趣的是这些属性的最新(即最新/准确)版本。如果有什么变化的话,我想知道这对我也很有用。(顺便说一句,如果日期、时间或地点发生变化,我还希望收到一封电子邮件/短信通知我,以防我没有查看更新的日程安排:-)

我建议在修改时间表时执行“差异”。因此,在创建类的版本2时,记录哪些值已更改,并将其存储在版本2对象的两个“changelog”字段中(必须有一个父表位于所有表的顶部-使用该表!)。一个变更日志字段是“人类可读文本”,例如“日期从5月1日星期一更改为5月2日星期二,时间从上午10:00更改为上午10:30”。第二个changelog字段是已删除的更改列表
 public class Person
 {
     public string name;
 }

 public class PersonComparer
 {
     public PersonComparer(Person old, Person new)
     {
        ....         
     }

     public bool NameIsDifferent() { return old.Name != new.Name; }
     public string NameDifferentText() { return NameIsDifferent() ? "Name changed from " + old.Name + " to " + new.Name : ""; }
 }
 public class ObjectComparer()
 {
    public ObjectComparer(object old, object new)
    {
        ...
    }

    public bool PropertyIsDifferent(string propertyName) { return getObjectProperty(old, propertyName) != getObjectProperty(new, propertyName) };

     public string PropertyDifferentText(string propertyName) { return PropertyIsDifferent(propertyName) ? propertyName + " " + changed from " + getObjectProperty(old, propertyName) + " to " + getObjectProperty(new, propertyName): ""; }
 }
}