Database design 数据库设计-如何随时间跟踪信息并查询表中的最新数据?

Database design 数据库设计-如何随时间跟踪信息并查询表中的最新数据?,database-design,Database Design,我们正在努力跟踪我们部门的应用程序和单元测试使用情况,因此我创建了一个数据库来跟踪这一情况。我有一个应用程序表,起初,我在应用程序表中创建了一个单元测试列,但我刚刚意识到,只要保持这个最新,它就会覆盖该应用程序的单元测试历史 由于我希望能够随着时间的推移提取此处的数据以生成显示进度的图表,因此我意识到我需要一个名为UnitTestTracking的单独表,该表包含以下列: ID(主密钥) 应用程序ID(int)\ 添加日期(日期时间) unittestcount(整数) 这样,人们可以每周或

我们正在努力跟踪我们部门的应用程序和单元测试使用情况,因此我创建了一个数据库来跟踪这一情况。我有一个应用程序表,起初,我在应用程序表中创建了一个单元测试列,但我刚刚意识到,只要保持这个最新,它就会覆盖该应用程序的单元测试历史

由于我希望能够随着时间的推移提取此处的数据以生成显示进度的图表,因此我意识到我需要一个名为UnitTestTracking的单独表,该表包含以下列:

  • ID(主密钥)
  • 应用程序ID(int)\
  • 添加日期(日期时间)
  • unittestcount(整数)
这样,人们可以每周或每月在此表中添加一次新条目,我们将有一个随时间推移的历史记录,以显示每个应用程序的进度以及所有应用程序的总进度

现在的一个问题是:由于不同的应用程序将在不同的时间在此表中添加条目,我如何对此表编写查询以获取所有应用程序的总计数

本质上(在伪SQL中)我需要如下内容:

“选择所有应用程序的单元测试计数,其中添加的应用程序数据是为该应用程序id添加的最新日期”


如何编写此查询?

您可以使用审核。这将创建所需的日志

要在不同的应用程序和单元测试之间进行分离,可以为每个应用程序创建单独的用户。 它将简化查询谁测试了什么。

“选择所有应用程序中的单元测试计数,其中添加的应用程序数据是为该应用程序id添加的最新日期”

恐怕我只能说,这种要求的表述似乎必然有缺陷

首先,查询中唯一的“自由变量”(即唯一的参数)似乎是“应用程序ID”

所以你的问题陈述似乎是:

(1) 给定一个应用程序ID,给我该应用程序ID的最新添加日期(即MAX(…)。 (2) 给定最新的日期,给我所有添加了日期等于(1)结果的应用程序 (3) 给定这组应用程序,请给出“这些应用程序”中的单元测试计数


第二:关于“跨越那些应用程序”,我必须说,我对关系代数的理解和对自然语言的理解都不能帮助我理解你(确切地)的意思。

我认为人们似乎在让这件事变得更难

要解决此问题,需要两个查询:

  • 为每个应用程序ID查找最新条目
  • 使用每个应用程序ID的最新条目给出单元测试计数的总和
  • 第一个方面的SQL是:

    SELECT application_ID, MAX(date_added) AS lastDateAdded FROM UnitTestTracking GROUP BY application_ID
    
    第二,我们通过嵌套查询来实现这一点:

    SELECT 
        SUM(unittestcount) 
    FROM 
        UnitTestTracking JOIN 
        (SELECT 
             application_ID, MAX(date_added) AS lastDateAdded 
         FROM 
             UnitTestTracking GROUP BY application_ID) T 
        ON UnitTestTracking.application_ID = T.application_ID AND 
           UnitTestTracking.date_added = T.LastDateAdded
    

    这将为您提供所需的信息,即当前的单元测试总数。

    这两个选项中的任何一个都适用于您的场景:

    1具有为应用程序添加新单元测试计数的逻辑,在历史记录中插入记录并更新应用程序记录的单元测试计数。然后在应用程序记录上使用一个简单的选择-历史记录在此场景中没有任何作用。这是最好的,如果你有大量的历史记录

    2直接对UnitTestTracking表使用此查询

    select application_id, unittestcount from UnitTestTracking u1 
    where date_added = ( 
       select max(date_added) from UnitTestTracking u2 
       where u1.application_id = u2.application_id 
    )
    

    我觉得原来的设计有点不对劲,所以比较复杂。下面的设计建议每天(或更频繁)输入,但对于特定的应用程序,由特定的人只计算当天。Kimball星形模式允许按日期、月份、年份、应用程序、人员、职务等进行简单的切片和切割。

    例如,在2008年、2009年、2010年的所有应用程序中

    SELECT  sum(TestCount) AS "Test Count"
    FROM    factTest AS f
            JOIN dimApplication AS a ON a.ApplicationID = f.ApplicationID
            JOIN dimPerson AS p ON p.PersonID = f.PersonID
            JOIN dimDate AS d ON d.DateID = f.DateID
    WHERE [Year] BETWEEN 2008 AND 2010
    
    在2009年的所有申请中,仅在星期五

    WHERE [Year] = 2009 AND DayOfWeek = 'Friday'
    
    2009年所有申请中,按个人列出

    SELECT  FullName, sum(TestCount) AS "Test Count"
    FROM    factTest AS f
            JOIN dimApplication AS a ON a.ApplicationID = f.ApplicationID
            JOIN dimPerson AS p ON p.PersonID = f.PersonID
            JOIN dimDate AS d ON d.DateID = f.DateID
    WHERE [Year] = 2009
    GROUP BY FullName
    
    2009年按申请、人员、月份,但仅限于周末

    SELECT  ApplicationName, FullName, [MonthName], sum(TestCount) AS "Test Count"
    FROM    factTest AS f
            JOIN dimApplication AS a ON a.ApplicationID = f.ApplicationID
            JOIN dimPerson AS p ON p.PersonID = f.PersonID
            JOIN dimDate AS d ON d.DateID = f.DateID
    WHERE [Year] = 2009 AND IsWeekend = 'Yes'
    GROUP BY ApplicationName, FullName, [MonthName]
    
    在2000-2009年的所有申请中,按年、按月,但仅限于由接待员在周二进行的测试

    SELECT  [Year], [Month], sum(TestCount) AS "Test Count"
    FROM    factTest AS f
            JOIN dimApplication AS a ON a.ApplicationID = f.ApplicationID
            JOIN dimPerson AS p ON p.PersonID = f.PersonID
            JOIN dimDate AS d ON d.DateID = f.DateID
    WHERE   [Year] BETWEEN 2000 AND 2009
            AND JobTitle = 'Receptionist'
            AND DayOfWeek = 'Tuesday'
    GROUP BY [Year], [Month]
    
    在所有的申请中,2009年的测试都是由养了两只或两只以上猫的矮个子在周末进行的

    SELECT  sum(TestCount) AS "Test Count"
    FROM    factTest AS f
            JOIN dimApplication AS a ON a.ApplicationID = f.ApplicationID
            JOIN dimPerson AS p ON p.PersonID = f.PersonID
            JOIN dimDate AS d ON d.DateID = f.DateID
    WHERE [Year] = 2009
          AND IsWeekend = 'Yes'
          AND IsShortPerson ='Yes'
          AND CatsOwned >= 2
    
    等等

    语法是sql server,但这里没有什么特别之处

    更新

    请注意,
    来自。。。参加参加JOIN…
    始终是相同的。所有的切片和切分都是通过
    SELECT,WHERE
    ,和
    groupby
    ——不需要“复杂的查询”。

    @Erwin OP不想获取单个应用程序的最新信息,它是所有应用程序的列表及其单元测试计数-请参见我的答案。+1使用内置审计肯定是另一种选择。我没有用它来主动显示结果/列表/过程历史信息,你知道它是否易于处理吗?例如,考虑到OP的要求,他们希望主动使用这些历史数据进行分析/绘制图表。@除了第一部分,你可能需要重新表述第二部分,以便更清楚地理解你的意思。考虑到应用程序将有一个标识符,它比收集信息时添加的应用程序标识符更自然——看起来不像添加单独的用户提供任何附加值。顺便说一句,关于另外两种方法,请参见我的答案。如果OP使用MSSQL或Oracle,那么查询审计表就像查询任何其他表一样简单。此外,您还可以使用审计工具为您进行分析。@Freddy,您不必为每个应用程序使用单独的用户。审核将已包含访问它的应用程序。但如果他使用的是DAL,那么唯一的区别就是使用不同的用户。所有这些都是在假设有几个应用程序正在使用