Database 如何最好地管理数据库中的历史查找值?

Database 如何最好地管理数据库中的历史查找值?,database,oracle,database-design,Database,Oracle,Database Design,概述 一个事件数据库,其中有许多列包含查找表中记录的ID 我试图解决的问题 我需要拿出一个健壮的解决方案来管理某些字段包含查找ID的历史数据。我列出了我提出的解决方案和备选方案。我想从其他开发人员那里了解他们是否在项目中以类似的方式管理这些场景。也许你有更好的方法 数据库:Oracle 10g 列:部门名称 场景:部门名称在一年中可以更改X次。业务部门需要报告其所有部门的数据,但希望看到事件发生时发生在其各自部门名下的事件 建议的解决方案:在部门名称查找表中设置条目时,设置开始和结束日期值。使

概述

一个事件数据库,其中有许多列包含查找表中记录的ID

我试图解决的问题

我需要拿出一个健壮的解决方案来管理某些字段包含查找ID的历史数据。我列出了我提出的解决方案和备选方案。我想从其他开发人员那里了解他们是否在项目中以类似的方式管理这些场景。也许你有更好的方法


数据库:Oracle 10g

:部门名称

场景:部门名称在一年中可以更改X次。业务部门需要报告其所有部门的数据,但希望看到事件发生时发生在其各自部门名下的事件

建议的解决方案:在部门名称查找表中设置条目时,设置开始和结束日期值。使用视图,根据事件日期创建计算字段,以便在任何给定时间点访问正确的部门名称

优点:通过一点防御性编码,它将允许选定用户通过GUI自助管理他们的静态数据,而无需任何额外的数据库更改。可以进行即时更改,例如完全更改名称。不需要DBA支持

缺点:考虑到在大型数据集上进行的大量查找/计算,这可能是一项昂贵的操作

替代解决方案:只需使用并插入部门名称的纯文本值即可。这里的缺点是,临时请求更改/更新值时需要DBA,可能会针对特定的日期范围,并且错误地丢失一些记录。表空间消耗也会增加


:指定的\u技术人员\u ID

场景:事件将指定一名技术人员,该技术人员的ID将存储在该位置。查找表将包含所有可用技术人员的“当前”列表。当人们离开公司时,必须刷新列表并删除过时的技术人员。这是为了将下拉列表中的值数量保持在最小值。业务部门仍然希望看到为其所有事件数据分配了哪些技术人员

解决方案:不要从技师查找表中删除条目,而是使用表示“已存档/已删除”的标志标记条目。此标志将充当GUI下拉列表上的过滤器,以删除不需要的条目

Pros:查找表将只包含来自员工表的技师的UID。因此,如果业务需求发生变化,则很容易在主视图中呈现技术人员的任何属性,例如全名或员工编号等

缺点:如前一示例所示,在大型数据集上查找可能是一项昂贵的操作。在GUI方面,需要在业务逻辑和设计方面进行额外的工作。特别是当原始条目已“存档”时如何管理下拉列表


替代解决方案:与上面的示例一样,只需使用纯文本值。这里的缺点是会消耗更多的表空间,并且随着业务需求的变化,灵活性会降低。

我是一名SQL Server开发人员,经常遇到这些问题。我从不喜欢使用文本(非规范化),除非我将数据加载到数据仓库

回复:部门名称

生效日期可能是最好的答案,让我停顿的是我不确定我是否理解这个问题。我想不出一个部门如此频繁地更名的商业案例

回复:AssignedTech


我在几乎所有基于员工的查找中都使用活动标志。我从未遇到过这样的性能问题。我在处理高周转率的公司时使用过过滤索引和视图

我是一名SQL Server开发人员,经常遇到这些问题。我从不喜欢使用文本(非规范化),除非我将数据加载到数据仓库

回复:部门名称

生效日期可能是最好的答案,让我停顿的是我不确定我是否理解这个问题。我想不出一个部门如此频繁地更名的商业案例

回复:AssignedTech


我在几乎所有基于员工的查找中都使用活动标志。我从未遇到过这样的性能问题。我在处理高周转率的公司时使用过过滤索引和视图

有一种称为版本控制的技术已经存在很多年了,但由于几个原因基本上不可行。然而,有一种类似的技术,我称之为版本范式,我发现它非常有用。下面是一个使用Employees表的示例

首先,创建静态表。这是主实体表,它包含关于实体的静态数据。静态数据是在实体的生命周期内预计不会更改的数据,例如出生日期

create table Employees(
  ID        int  auto_generated primary key,
  FirstName varchar( 32 ),
  Hiredate  date not null,
  TermDate  date,            -- last date worked
  Birthdate date,
  ...              -- other static data
);
认识到每个员工都有一个条目很重要,就像任何这样的表一样

然后是关联的版本表。这将与静态表建立1-m关系,因为一个员工可能有多个版本

create table Employee_versions(
  ID         int   not null,
  EffDate    date  not null,
  char( 1 )  IsWorking not null default true,
  LastName   varchar( 32 ),    -- because employees can change last name
  PayRate    currency not null,
  WorkDept   int   references Depts( ID ),
  ...,              -- other changable data
  constraint PK_EmployeeV primary key( ID, EffDate )
);
在版本表注释中,有一个生效日期,但没有匹配的“不再生效”字段。这是因为一旦某个版本生效,它将一直保持有效,直到被后续版本替换。ID和EffDate的组合必须是唯一的,因此同一员工的两个版本不能同时处于活动状态,时间版本之间也不能有间隙
select  ...
from    Employees e
join    Employee_versions v1
    on  v1.ID = e.ID
    and v1.EffDate =(
        select  Max( v2.EffDate )
        from    EmployeeVersions v2
        where   v2.ID = v1.ID
            and v2.EffDate <= NOW()
    )
where  e.ID = :EmpID;