【问题标题】:how to make history of sql data? (report data changes)如何制作sql数据的历史记录? (报告数据变化)
【发布时间】:2015-07-11 04:25:03
【问题描述】:

每天,我都将(使用 crontab、php 脚本)保存到数据库错误信息中。每一行都是这样的: (错误识别、日期、标题、谁等......)

(例如: 错误识别、日期、标题、谁等......

issue1, 2015-04-01, blabla, bill 等...

issue2, 2015-04-01, nnnnnnn, john 等...

issue3, 2015-04-01, vvvvvvv, greg 等...

issue1, 2015-04-02, blabla, bill 等...

issue2, 2015-04-02, nnnnnnn, john 等...

issue3, 2015-04-02, vvvvvvv, mario, etc...(现在是 mario)

issue2, 2015-04-03, nnnnnnn, john 等...(issue1 消失了)

issue3, 2015-04-03, vvvvvvv, tod, etc...(tod 是新信息)

issue4, 2015-04-03, rrrrrrrr, john 等...(issue4 是新的)

.................................................. )

基本上,如果我以上面发布的示例为例,结果应该类似于 4 月 2 日和 4 月 3 日之间的比较

新行是:issue4

关闭的行是:Issue1

更新的行是:Issue3(用 tod 代替 mario)

没有变化的行是:Issue2

在我的例子中,有数百行,我相信我知道如何做到这一点,这要归功于 php,但我的代码将很长,就像创建 foreach 循环并一一查看是否有任何更改。我不确定我是否得到了直接的解决方案。

所以我的问题是,是否有任何简单的方法可以使用“简单”代码(如 sql 特殊请求或任何项目代码或简单的 php 函数?)来报告这些更改。

【问题讨论】:

  • 可能您需要一个SELECT 语句,其中包含WHERE 条件和日期BETWEEN。通过这种方式,您将能够从数据库中仅获取您感兴趣的行
  • 感谢您的回复,但我的意思是精确比较 2 个日期,然后知道哪一行是新的,哪一行是关闭的,哪一行是更新的,哪一行是不变的。
  • 最好的事情是,如果您还发布输入参数的示例和您期望的最终结果
  • 我明白你的意思,但我不能,因为数据是机密的,仅供内部使用。
  • 您不必复制真实数据,只需复制足够相似的数据即可制作可重现的示例

标签: php sql report history


【解决方案1】:

这个设计中有太多的假设。这些假设要求您首先比较不同日期之间的行以做出假设 - 更不用说您必须从一天到下一天复制未更改的行,以维持提供假设所需的不间断的每日条目。呼。

规则 1:不要在设计中建立假设。如果有东西是新的,它应该被标记,“嘿!我是新来的!”当对数据进行更改时,“好的,发生了一些变化。就是这样。”当问题最终结束时,“好吧,我就这样了。我已经完成了。”

create table Bug_Static( -- Contains one entry for each bug
    ID     int identity,
    Opened date not null default sysdate,
    Closed date [null | not null default date '9999-12-31'],
    Title  varchar(...),
    Who    id references Who_Table,
    <other non-changing data>,
    constraint PK_Bug_Static primary key( ID )
);
create table Bug_Versions( -- Contains changing data, like status
    ID        int not null,
    Effective date not null,
    Status    varchar not null,  -- new,assigned,in work,closed,whatever
    <other data that may change from day to day>,
    constraint PK_Bug_Versions primary key( ID, Effective ),
    constraint FK_Bug_Versions_Static foreign key( ID )
        references Bug_Static( ID )
);

现在您可以选择任意一天的错误和当前数据(最后一次更改)。

select  s.ID, s.Opened, s.Title, v.Effective, v.Status
from    Bug_Static   s
join    Bug_Versions v
    on  v.ID = s.ID
    and v.Effective =(
        select  Max( Effective )
        from    Bug_Versions
        where   ID = v.ID
            and Effective <= sysdate )
where   s.Closed < sysdate;

where s.Closed &lt; sysdate 是可选的。这给你的是在查询执行之日关闭的所有错误,但不是在那之前关闭的错误。这样可以防止已关闭的错误一遍又一遍地重新出现——除非这是你想要的。

sysdate 值更改为特定日期/时间,您将获得截至该日期和时间的数据。

通常,当创建错误时,会在两个表中输入一行。然后仅输入新版本作为状态或任何其他数据更改。如果一天没有任何变化,则不输入任何内容。然后当 bug 最终关闭时,更新静态表的Closed 字段,并在版本表中插入一个closed 版本。我已经向Closed 字段展示了两个选项,即 null 或定义的“最大日期”为 9999 年 12 月 31 日。您可以使用任何一个,但我喜欢最大日期方法。它简化了查询。

我还会在两个表的前面加上几个视图来连接这些表。一个只显示每个 bug 的最新版本 (Bug_Current),另一个显示每个 bug 的每个版本 (Bug_History)。使用 Bug_Current 上的触发器,它可以是应用程序用来更改错误的触发器。例如,它将任何版本化字段的更新更改为插入新版本。

关键是,这是一个非常灵活的设计,您可以随时轻松地显示您想要的数据、您想要的数据。

【讨论】:

  • 您好,非常感谢您的详细反馈。对我来说,设计的一部分不是来自我,我必须处理它。无论如何,我同意您的解决方案更加优化。由于我无法更改现有设计,我唯一的解决方案是创建 php 脚本。实际上我的问题的根源是知道简单的命令是否可以解决它。好像没有,
  • 这就是为什么我尽可能强调使用视图的重要性。应用程序代码不应直接访问表。当他们这样做时,对表格进行最轻微的更改可能需要大量的时间和精力——如果允许的话。当他们只接触视图时,对表的更改是例行公事。只需更新关联的视图,应用程序代码甚至都不知道进行了更改。这么简单。
猜你喜欢
  • 2010-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
  • 2023-01-07
相关资源
最近更新 更多