SQL选择标准目前的记录从审计日志的问题
题
我的记忆都失败了我。我有一个简单的审计日志表基于一个触发器:
ID int(身份,PK)
客户id int
名称 varchar(255)
地址 varchar(255)
AuditDateTime datetime
AuditCode char(1)
它具有这样的数据:
ID 客户id 名称 地址 AuditDateTime AuditCode
1 123 鲍勃 123互联网方式 2009-07-17 13:18:06.353我
2 123 鲍勃 123互联网方式 2009-07-17 13:19:02.117D
3 123 杰瑞 123互联网方式 2009-07-17 13:36:03.517我
4 123 鲍勃 123我的编辑方式 2009-07-17 13:36:08.050U
5 100 阿诺德 100天网的方式 2009-07-17 13:36:18.607我
6 100 尼基 100星的方式 2009-07-17 13:36:25.920U
7 110 金发女郎 110另一种方式 2009-07-17 13:36:42.313我
8 113 莎莉 113然而,另一种方式 2009-07-17 13:36:57.627我
什么是有效的选择的发言将得到所有最新的记录之间的一开始和结束时间? 供参考:我为插入,D删除,并为更新。
我错过了什么审计表?我的下一步是创建一个审计表中,只记录的更改,但可以提取的最近的记录对于给定的时间框架。为了我的生活我不能找到任何搜索引擎容易。链接会的工作。谢谢你的帮助。
解决方案
另一个(更好的?) 方法保持审计历史记录是使用'startDate"和"结束日期列,而不是一个auditDateTime和AuditCode列。这是常有的做法在跟踪类型2的变化(新版本的行)在数据仓库。
这可以让你更直接选择的当前行(这里结束日期是NULL),并且你将不需要治疗的更新不同于插入或删除。你只有三种情况:
- 插入:复制完整的行与一个开始日期和NULL结束日期
- 删除:设定的结束日期的现有电流行(结束日期是NULL)
- 更新:做一个删除,然后插入
你的选择就是:
select * from AuditTable where endDate is NULL
无论如何,这是我的查询现有的架构:
declare @from datetime
declare @to datetime
select b.* from (
select
customerId
max(auditdatetime) 'auditDateTime'
from
AuditTable
where
auditcode in ('I', 'U')
and auditdatetime between @from and @to
group by customerId
having
/* rely on "current" being defined as INSERTS > DELETES */
sum(case when auditcode = 'I' then 1 else 0 end) >
sum(case when auditcode = 'D' then 1 else 0 end)
) a
cross apply(
select top 1 customerId, name, address, auditdateTime
from AuditTable
where auditdatetime = a.auditdatetime and customerId = a.customerId
) b
参考文献
一个 cribsheet数据仓库, 但有一个良好的部分在类型2的变化(你想要什么跟踪)
MSDN页上 数据仓库
其他提示
确定,对于审计日志表几件事情。
对于大多数应用程序,我们希望审计表是在插入极快。
如果审计日志是真正用于诊断或非常不规则审计的原因,然后最快插入标准是使在插入时间表物理排序。
和这意味着把审计时间作为聚簇索引的第一列,e.g。
create unique clustered index idx_mytable on mytable(AuditDateTime, ID)
这将允许在AuditDateTime O(log n)的,和O(1)插入。
极其有效的选择查询如果你想看看你的审计表上每个客户ID的基础上,那么你就需要妥协。
您可以增加时(客户ID,AuditDateTime)非聚集索引,这将允许为O(log n)的每个客户审核历史的查找,但是成本将是聚簇索引的插入时的维护 - 保养将为O(log n)的相反。
但是,这种插入的时间损失可能是最好的表扫描(即O(n)的时间复杂性成本),您将需要如果你没有CustomerID上的索引付出,这是一个普通的查询执行。 为O(n)查找其锁定表为一个不规则的查询可能会堵塞作家写作过程中,所以它有时是作家的利益,如果它保证读者不会被阻止他们提交稍微慢一些,因为读者需要表扫描,因为缺乏一个很好的指标,以支持他们......
增加:如果你正在寻找限制给定的时间内,最重要的首先是在AuditDateTime索引。并使其聚集因为你是在AuditDateTime顺序插入。这是你可以做,使您的查询从一开始就有效最重要的事情。
接下来,如果你正在寻找一个给定的时间跨度内最近更新的所有客户ID的,以及此后需要对数据进行完全扫描,通过插入日期限制。
您需要根据您的审计表做一个子查询的范围之间,
select CustomerID, max(AuditDateTime) MaxAuditDateTime
from AuditTrail
where AuditDateTime >= @begin and Audit DateTime <= @end
和然后将此主题融入影片选择查询适当的,例如
select AuditTrail.* from AuditTrail
inner join
(select CustomerID, max(AuditDateTime) MaxAuditDateTime
from AuditTrail
where AuditDateTime >= @begin and Audit DateTime <= @end
) filtration
on filtration.CustomerID = AuditTrail.CustomerID and
filtration.AuditDateTime = AuditTrail.AuditDateTime
另一种方法是使用一个子选择
select a.ID
, a.CustomerID
, a.Name
, a.Address
, a.AuditDateTime
, a.AuditCode
from myauditlogtable a,
(select s.id as maxid,max(s.AuditDateTime)
from myauditlogtable as s
group by maxid)
as subq
where subq.maxid=a.id;
开始和结束时间? e.g在凌晨1点之间凌晨3点点击 或开始和结束日期时间? e.g如2009-07-17 13时36分至13点36分2009-07-18